在Django中解决模型之间的两种不同关系

时间:2011-04-01 03:24:50

标签: sql django django-models

我有一个经纪人模型和一个城市模型,其中Broker模型定义如下:

class Broker(models.Model):
    user = models.ForeignKey(Auth)
    areas_of_operation = models.ManyToManyField(City)
    phone = models.CharField(max_length=20)
    company_name =  models.CharField(max_length=50)
    address1 = models.CharField(max_length=100)
    address2 = models.CharField(max_length=100)
    city = models.ForeignKey(City)
    state = models.ForeignKey(State, unique=True)
    zip = models.IntegerField(max_length=5)

当然这会产生错误,但我想知道是否有任何方式可以促进一种关系,表明经纪人可以在许多城市工作但只住在一个城市。或者这是一个高级设计问题,我必须创建更多表来显示这种关系?

1 个答案:

答案 0 :(得分:3)

当您创建从一个模型到另一个模型的关系时,Django会自动在另一个方向上添加反向关系。例如,如果您暂时删除了areas_of_operation字段,它就会起作用,您可以使用代码city.broker_set()来获取居住在特定城市的所有经纪人。

但是,当您从一个模型创建多个链接到另一个模型时,Django会尝试在相同的属性名称下创建多个反向关系。当您在模型上运行manage.py validate时,错误消息会证实这一点:

Error: One or more models did not validate:
myapp.broker: Accessor for field 'city' clashes with related m2m field 'City.broker_set'. Add a related_name argument to the definition for 'city'.
myapp.broker: Accessor for m2m field 'areas_of_operation' clashes with related field 'City.broker_set'. Add a related_name argument to the definition for 'areas_of_operation'.

换句话说,问题不在于具有从BrokerCity的多个链接,而是具有两个链接的相同默认名称的自动反向关系。要解决此问题,请使用related_name参数设置用于反向关系的名称。以下代码对我有用:

from django.contrib.auth.models import User
from django.db import models

class State(models.Model):
    name = models.CharField(max_length=100)

class City(models.Model):
    name = models.CharField(max_length=100)

class Broker(models.Model):
    user = models.ForeignKey(User)
    areas_of_operation = models.ManyToManyField(City, related_name='operators')
    phone = models.CharField(max_length=20)
    company_name =  models.CharField(max_length=50)
    address1 = models.CharField(max_length=100)
    address2 = models.CharField(max_length=100)
    city = models.ForeignKey(City, related_name='citizens')
    state = models.ForeignKey(State, unique=True)
    zip = models.IntegerField(max_length=5)

现在,如果您有City个对象,则可以致电city.operators()以获取该城市中的运营人员列表,并city.citizens()查看居住在该城市的人员列表。< / p>

有关关系字段的详细信息,请参阅Django model field documentation