我希望能够通过一个列加入两个模型,这两个模型在任何一个模型中都不是唯一的。
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。感谢。
答案 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
解决它!)。