Django如何创建指向同一个模型的多个外键?

如下所示的House模型,其”province“, "city"和"district"字段类型是指向Region模型的外键。

  1. class Region(models.Model):  
  2.     """行政区域表 
  3.     国家,省,市,区(县) 
  4.     """  
  5.     parent = models.ForeignKey('self')  
  6.     name = models.CharField(max_length=30)  
  7.     region_type = models.IntegerField()  
  8.   
  9.     class Meta:  
  10.         db_table = "regions"  
  11.           
  12. class House(models.Model):  
  13.     """房屋表 
  14.     """  
  15.     province = models.ForeignKey(Region)  
  16.     city = models.ForeignKey(Region)  
  17.     district = models.ForeignKey(Region)  
  18.     address = models.CharField(max_length=200)  
  19.     name = models.CharField(max_length=200)  
  20.     longitude = models.FloatField() # 经度  
  21.     latitude = models.FloatField() # 纬度  
  22.     created_at = models.DateTimeField(auto_now_add=True)  
  23.     updated_at = models.DateTimeField(auto_now=True, null=True)   

表面上看起来好像没有问题,但是进行syncdb时,就会出现”house.house: Accessor for field 'province' clashes with related field 'Region.house_set'. Add a related_name argument to the definition for 'province'....“错误。

原因是指向同一模型的三个外键反向关联名称产生了冲突,Region模型对province的反向关联名称为house_set(),对city的反向关联名称也是house_set(),对district的反向关联名称还是house_set()。

解决方法:给models.ForeignKey()加入related_name参数,定义不同的关联名称。如下代码:

  1. class House(models.Model):  
  2.     """房屋表 
  3.     """  
  4.     province = models.ForeignKey(Region, related_name='province_houses')  
  5.     city = models.ForeignKey(Region, related_name='city_houses')  
  6.     district = models.ForeignKey(Region, related_name='district_houses')  
  7.     address = models.CharField(max_length=200)  
  8.     name = models.CharField(max_length=200)  
  9.     longitude = models.FloatField() # 经度  
  10.     latitude = models.FloatField() # 纬度  
  11.     created_at = models.DateTimeField(auto_now_add=True)  
  12.     updated_at = models.DateTimeField(auto_now=True, null=True)   

 

参考文章:Relating a model to another model more than once


Model source code

from django.db import models

class Person(models.Model):
    full_name = models.CharField(max_length=20)
    mother = models.ForeignKey('self', null=True, related_name='mothers_child_set')
    father = models.ForeignKey('self', null=True, related_name='fathers_child_set')

    def __unicode__(self):
        return self.full_name

Sample API usage

This sample code assumes the above model has been saved in a file<tt literal"="">mysite/models.py.

>>> from mysite.models import Person

# Create two Person objects -- the mom and dad in our family.
>>> dad = Person(full_name='John Smith Senior', mother=None, father=None)
>>> dad.save()
>>> mom = Person(full_name='Jane Smith', mother=None, father=None)
>>> mom.save()

# Give mom and dad a kid.
>>> kid = Person(full_name='John Smith Junior', mother=mom, father=dad)
>>> kid.save()

>>> kid.mother
<Person: Jane Smith>
>>> kid.father
<Person: John Smith Senior>
>>> dad.fathers_child_set.all()
[<Person: John Smith Junior>]
>>> mom.mothers_child_set.all()
[<Person: John Smith Junior>]
>>> kid.mothers_child_set.all()
[]
>>> kid.fathers_child_set.all()
[]

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值