当前位置:  开发笔记 > 后端 > 正文

Django中的OneToMany关系锁定了一个模型

如何解决《Django中的OneToMany关系锁定了一个模型》经验,为你挑选了1个好方法。

我知道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?



1> Shang Wang..:

您可以创建另一个中间模型,然后将电话号码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().

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有