Django模特:为什么名字冲突?

时间:2010-02-07 20:08:33

标签: django django-models

首先,我知道如何解决问题,我只是想了解它为什么会发生。错误消息:

  

users.profile:字段'address'的反向查询名称与相关字段'Address.profile'冲突。添加related_name a   对“地址”定义的争论。

代码:

class Address(models.Model):
    country = fields.CountryField(default='CA')
    province = fields.CAProvinceField()
    city = models.CharField(max_length=80)
    postal_code = models.CharField(max_length=6)
    street1 = models.CharField(max_length=80)
    street2 = models.CharField(max_length=80, blank=True, null=True)
    street3 = models.CharField(max_length=80, blank=True, null=True)

class Profile(Address):
    user = models.ForeignKey(User, unique=True, related_name='profile')
    primary_phone = models.CharField(max_length=20)
    address = models.ForeignKey(Address, unique=True)

如果我理解正确,这一行:

address = models.ForeignKey(Address, unique=True)

将导致将属性添加到名为Address的{​​{1}}类中。是什么创建其他“个人资料”名称?


如果我不需要反向名称怎么办?有没有办法禁用它?地址用于十几种事情,因此大多数反向关系无论如何都是空白的。

有没有办法将地址字段复制到模型中,而不是为地址设置单独的表?没有Python继承(这没有意义,如果Model有2个地址,它就不起作用)。

4 个答案:

答案 0 :(得分:24)

django docs中说:

如果您更喜欢Django没有创建向后关系,请将related_name设置为“+”。例如,这将确保用户模型不会与此模型建立向后关系:

user = models.ForeignKey(User, related_name='+')

但我自己从未尝试过......

答案 1 :(得分:1)

我不确定错误的profile字段来自哪里......但找到的一种方法是:从个人资料中临时删除address = models.ForeignKey(…)./manage.py shell,{{1}然后看看from ... import Address会告诉你什么。

我认为没有任何官方方法可以在不使用继承的情况下仅继承其他模型中的字段......但是你可以像这样伪造它(Address.profile就是这样,例如SourceModelAddress例如是TargetModel):

Profile

(这来自Django's ModelBase __new__ implementation

答案 2 :(得分:0)

我认为不可能禁用反向名称。

我刚刚对代码进行了快速grep,看起来似乎没有任何逻辑可以绕过在相关模型上设置related_name字段。

答案 3 :(得分:0)

例如:仅添加“ +”

class GeneralConfiguration(models.Model):

created_at = models.DateTimeField(editable=False, default=settings.DEFAULT_DATE)
updated_at = models.DateTimeField(editable=False, default=settings.DEFAULT_DATE)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.PROTECT, related_name='+')
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.PROTECT, related_name='+')