【问题标题】:Django OneToOneField allow online one referenceDjango OneToOneField 允许在线一个参考
【发布时间】:2019-11-18 11:35:06
【问题描述】:

我正在尝试创建一对一的引用,并希望确保该引用不允许用于另一个模型或实例。

例如

假设我有一个地址模型、个人模型和公司模型

Person 有一个 OneToOneField 字段到地址 公司还有一个 OneToOneField 字段用于地址

address=Address(data="some address")
company=Company(name="some company",address=address)
person=Person(name="my name",address=address)

型号:

class Address(models.Model):
  data = models.CharField(max_length=255, blank=True, null=True)
class Company(models.Model):
  name = models.CharField(max_length=255, blank=True, null=True)
  address=models.OneToOneField(Address,on_delete=models.CASCADE)
class Person(models.Model):
  name = models.CharField(max_length=255, blank=True, null=True)
  address=models.OneToOneField(Address,on_delete=models.CASCADE)

我希望系统对此抛出错误,因为我为 2 个不同的模型设置了相同的地址。

如果我删除地址,这也会删除个人和公司。

通常你可以用代码捕捉到这一点,而不会犯这样的愚蠢错误。 但是由于是一对一的,系统能抓到吗?

【问题讨论】:

    标签: python django model


    【解决方案1】:

    在删除的情况下,您可以使用on_delete=models.PROTECT。在另一种情况下,您可以添加unique=True,这样一个人 id = 1 将有一个地址 id = 1,一个人 id = 2 不能再有一个地址 id = 1。但它只能解决一个模型:
    address=models.ForeignKey(Address, unique=True, on_delete=models.PROTECT)

    一种新方法是创建一个模型来引用公司和个人的地址,并能够禁止使用相同的地址 id 创建:

    class AddressExample(models.Model):
        id_address = models.ForeignKey(Address, unique=True,on_delete=models.PROTECT)
        id_person = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)
        id_company = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)  
    

    请注意,我使用了blank=True, null=True,因此您可以仅使用 Person 或 Company 创建实例,而无需同时创建两者的实例。还有一个 Meta 可以使用主键组合。

    class AddressExample(models.Model):
        id_address = models.ForeignKey(Address, unique=True,on_delete=models.PROTECT)
        id_person = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)
        id_company = models.ForeignKey(Person, blank=True, null=True, unique=True, on_delete=models.PROTECT)
    
       class Meta:
           unique_togther = ('id_address', 'id_person', 'id_company')
           # Not sure if it will throw a error here because `id_person` and `id_company` can be blank 
           # or null. But the use of `unique together` is for cases where you want to guarantee 
           # the combination of the primary keys will be unique.
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-16
      • 2012-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多