【问题标题】:Best way to get around the unique-constraint for many-to-many relationships in Django?绕过Django中多对多关系的唯一约束的最佳方法?
【发布时间】:2018-05-01 05:59:29
【问题描述】:

我需要能够将同一对象的多个副本添加到多对多关系中。

假设问题在于记录某人拥有的家具类型。这是我的基本模型:

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

class Furniture(models.Model):
    furniture_name = models.CharField(max_length=100) #e.g. Chair, Sofa.

假设我想记录 Sam 拥有 3 张椅子和 2 张沙发。但我不想在数据库中创建多个 sofa 对象。我怎样才能通过多对多关系做到这一点?传统的多对多具有防止这种情况发生的唯一约束。

我正在考虑使用一个直通表,其中包含唯一约束中的另一个字段(购买日期,或者只是一个随机字符串)。这行得通吗?

有人有更好的方法吗?

【问题讨论】:

标签: python sql django


【解决方案1】:

在这里创建一个直通表是一个很好的方法,因为一切都将是干燥的并且非常易于使用:

class Ownership:
    owner = models.ForeignKey(Person, on_delete=models.CASCADE)
    furniture = models.ForeignKey(Furniture, on_delete=models.CASCADE)

    items_owned = models.IntegerField(default=0)

    class Meta:
        unique_together = [
            'owner', 'furniture'
        ]

person = Person.objects.get(name='Bob')
furniture = Furniture.objects.get(furniture_name='Sofa')

# update the number of items owned
Ownership.objects.update_or_create(
    owner=person, furniture=furniture, defaults=dict(items_owned=3))

# get the number of items owned
person.ownership_set.get(furniture=furniture).items_owned

# or for example
Ownership.objects.get(owner__name='Bob', furniture__name='Sofa').items_owned

然后,您可以使用自定义管理器 https://docs.djangoproject.com/en/2.0/topics/db/managers/#custom-managers 抽象出这种复杂的查询和更新逻辑

【讨论】:

  • 谢谢,这是一个非常有用的答案。我特别欣赏如何获取 items_owned 的示例。
  • Django docs 声明 unique_together 将来可能会被 models.UniqueConstraint 弃用。可能这个答案应该相应更新
猜你喜欢
  • 2018-06-29
  • 1970-01-01
  • 2015-02-27
  • 2010-10-08
  • 2020-03-19
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多