我知道ForeignKeys和OneToOneFields是什么,以及ManyToManyField,它们如何工作以及何时使用它们。但是,我正在使用一个项目,该项目的 Many 部分无法修改。所以,假设I want to let a user have many phone numbers,我通常会这样做:
# my_app/models.py
from django.db import models
class User(Model):
...
class PhoneNumber(models.Model):
user = models.ForeignKey(User)
我遇到的问题是我的PhoneNumber
模型等效来自第三方软件包,已经填充了记录,而不是我自己的应用程序中的子类。那是
# third_party_django_package/models.py
from django.db import models
class PhoneNumber(models.Model):
# This cannot change
# my_app/models.py
from django.db import models
from third_party_django_package.models import PhoneNumber
class User(Model):
# These do not work -- a user can have more than one phone number
phone_number = models.ForeignKey(PhoneNumber)
phone_number = models.OneToOneField(PhoneNumber)
# This is close, but I want a phone number to belong to only one User
phone_numbers = models.ManyToManyField(PhoneNumber, related_name=...)
def clean(self):
# Validating the M2M relation costs extra queries, is slow, and
# is prone to race conditions
这都是伪代码。
不使用yet another third-party package来访问Django的内部成员,这使得项目更加向前兼容,我还有什么选择来实现具有正确模式级约束的正确OneToManyField?< / p>
答案 0 :(得分:8)
您可以创建另一个中间模型,然后将电话号码OneToOneField设置为该模型,然后在该模型中将User定义为ForeignKey。
class UserPhoneNumber(models.Model):
phone_number = models.OneToOneField(PhoneNumber)
user = models.ForeignKey(User)
这有点麻烦,但至少可以实现你所需要的。
修改强>
正如@Daniel所说,可以使用与through
模型的m2m关系,并在字段上使用unique_together
来执行此操作:
class User(Model):
phone_numbers = models.ManyToManyField(PhoneNumber, through=UserPhoneNumber)
class UserPhoneNumber(Model):
phone_number = models.ForeignKey(PhoneNumber)
user = models.ForeignKey(User)
class Meta:
unique_together = ('phone_number', 'user')
如果您想通过numbers = user.phone_numbers.all()
查看用户的电话号码,这将使您的生活更轻松。