1

现在我正在使用 Django 的内置管理系统来管理用户,我已经附加了一个配置文件以包含使用以下内容的其他数据:

class Profile(models.Model):
    user = models.OneToOneField(User, editable = False)
    # Data fields here...

就目前而言,当且仅当在创建用户后立即创建配置文件时,用户和配置文件 pk(以及相应的 id 编号)将是相同的。我可以保证在注册过程中会出现这种情况,虽然这将涵盖大多数用途,但使用管理界面创建用户可能会导致不匹配的 id 发生。因此,这似乎不是解决此问题的一种非常可靠的方法,我想将 pk 硬编码为相同的。我不知道该怎么做。

我认为以下方法会起作用:

profile_id = models.IntegerField(default=user.pk, editable = False, 
                                 primary_key = True)

但这给了我错误:

AttributeError: 'OneToOneField' has no attribute 'pk'

保证配置文件和用户具有相同pk的最佳方法是什么?注意:我真的不想处理扩展基本用户模型,因为使用 OneToOneField 链接两者似乎足以满足我的所有需求。

谢谢!

[编辑]

我提出这个问题的理由:

我的直接问题是我想要一个用户配置文件值的字典,我正在使用profile_values = Profile.objects.filter(pk=user.id).values()[0]. 这突出了这个错误,我昨晚用它“破解”了它pk=user.profile.id。在早上的光线下,这看起来不像是一个可怕的黑客攻击。然而,似乎有 pk 差异可能会导致安静且难以捕捉到错误,因此迫使它们匹配将是一个好主意。但我是 Django 的新手,所以我完全接受,事实上,如果你正确地编写你的代码,这从来都不是问题。也就是说,几乎出于学术原因,我很想知道如何解决这个问题

[/编辑]

4

2 回答 2

0

pkfilter()查询中的参数,但不是字段名称。您可能想使用user.id.

于 2013-06-14T21:15:52.663 回答
0

就像您已经同意这从来都不是问题一样,因为我们在两个模型之间有一个 OneToOne 映射。所以当你需要获取一个User对应的profile obj时:

profile_values = Profile.objects.get(user_id=user)

假设,

class Profile(models.Model):
    user = models.OneToOneField(User)
    ...

如果您的列名不是用户,则在获取查询中使用相应的名称。

不过,如果您对如何为两个模型实现相同的 pk 感到好奇,那么我们可以在每次保存 User 模型时设置一个信号。请参阅文档

def create_profile(sender, **kwargs):
    if kwargs["created"]:
        p = Profile(user=kwargs["instance"], ...)
        p.save()
django.db.models.signals.post_save.connect(create_profile, sender=User)

每次保存任何用户对象时都会调用 create_profile()。在这个函数中,我们仅在创建了新的 User 实例时才创建 Profile 对象。

如果我们从空白开始,那么我认为这将始终确保每个用户都存在一个配置文件,并且是在创建用户之后立即创建的;这反过来将为两种模型提供相同的pk。

于 2013-06-17T12:39:13.230 回答