如何加入django中的两个非唯一列?

时间:2010-11-19 17:55:03

标签: django django-models

我希望能够通过一个列加入两个模型,这两个模型在任何一个模型中都不是唯一的。

class Ctystate(models.Model):
    ctystate_id = models.IntegerField(primary_key=True)
    zip5 = models.IntegerField()
    [...]

class Addr2zip(models.Model):
    addr2zip_id = models.IntegerField(primary_key=True)
    ctystate = models.ForeignKey(Ctystate, db_column='zip5', to_field='zip5')
    zip5 = models.IntegerField()
    [...]

使用ForeignKey字段只会导致模型验证错误:

  

模型'Addr2zip'下的字段'zip5'必须具有唯一的= True约束。

有没有办法可以使用'zip5'字段加入这两个模型?我确实意识到这可能会导致结果重复,但是还会对过滤器中使用的内容进行其他保护。

我也不想有中间表。如果必须,我可以编写自己的SQL,但我尽可能地坚持使用ORM。感谢。

2 个答案:

答案 0 :(得分:1)

美国的单个邮政编码可能包含> 1个城市。一个城市绝对可以拥有> 1个邮政编码,因此您需要一个ManyToMany关系。

此外,邮政编码可以越过州界线,并且有跨越州界的城市(例如堪萨斯城),但正式地,每个市政府只属于一个州。

数据模型取决于您想要解释的方式。

很可能你甚至不需要使用合理的模型来运行这样的连接。

虽然您希望保持模型不变(您需要检查真实的表名),但这样的事情可能会有效:

addr_list = Ctystate.objects.extra(
    select = {
        'city_name': 'ctystate.name',
        'addr': 'addr2zip.address'
    },
    where = ['ctystate.zip5 = addr2zip.zip5'],
    tables = ['ctystate', 'addr2zip']#assuming that those are names in your table
)

答案 1 :(得分:0)

我认为你应该能够像这样解决它:

class Ctystate(models.Model):
    ctystate_id = models.IntegerField(primary_key=True)
    zip5 = models.IntegerField(unique=True)

class Addr2zip(models.Model):
    addr2zip_id = models.IntegerField(primary_key=True)
    ctystate = models.ForeignKey(Ctystate, db_column='zip5', to_field='zip5')

如果你这样做,ForeignKey ctystate将由名为zip5的db列中的zip5值表示。如果要使用外键实现,则必须将to_field设置为unique=True,否则它将不再是1:n(外键)关系(每个Addr2zip对象都可以否则与多个Ctystate对象相关,这将是am:n关系 - 如果你需要这个,你必须使用ManyToManyField解决它!)。