我知道ForeignKeys和OneToOneFields是什么,以及ManyToManyField,它们是如何工作的,以及何时使用它们.但是,我正在处理一个项目,该项目的很多部分都无法修改.所以,假设我想让用户拥有多个电话号码,我通常会这样做:
# 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
这都是伪代码.
如果不使用另一个访问Django内部成员的第三方软件包,这会使项目更加向前兼容,那么我还有哪些选择来实现具有正确模式级别约束的正确OneToManyField?
您可以创建另一个中间模型,然后将电话号码OneToOneField设置为该模型,然后在该模型中将User定义为ForeignKey.
class UserPhoneNumber(models.Model): phone_number = models.OneToOneField(PhoneNumber) user = models.ForeignKey(User)
这有点麻烦,但至少它可以实现你所需要的.
编辑:
正如@Daniel所说,使用m2m与through
模型的关系可以做到这一点,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()
.