如下所示的House模型,其”province“, "city"和"district"字段类型是指向Region模型的外键。
- class Region(models.Model):
- """行政区域表
- 国家,省,市,区(县)
- """
- parent = models.ForeignKey('self')
- name = models.CharField(max_length=30)
- region_type = models.IntegerField()
- class Meta:
- db_table = "regions"
- class House(models.Model):
- """房屋表
- """
- province = models.ForeignKey(Region)
- city = models.ForeignKey(Region)
- district = models.ForeignKey(Region)
- address = models.CharField(max_length=200)
- name = models.CharField(max_length=200)
- longitude = models.FloatField() # 经度
- latitude = models.FloatField() # 纬度
- created_at = models.DateTimeField(auto_now_add=True)
- 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参数,定义不同的关联名称。如下代码:
- class House(models.Model):
- """房屋表
- """
- province = models.ForeignKey(Region, related_name='province_houses')
- city = models.ForeignKey(Region, related_name='city_houses')
- district = models.ForeignKey(Region, related_name='district_houses')
- address = models.CharField(max_length=200)
- name = models.CharField(max_length=200)
- longitude = models.FloatField() # 经度
- latitude = models.FloatField() # 纬度
- created_at = models.DateTimeField(auto_now_add=True)
- 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() []