首页 > 解决方案 > 如何在 Django 中重复多对多关系?

问题描述

我的 Django 应用中有这些模型:

from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()


class Animal(models.Model):
    name = models.CharField(max_length=100, unique=True)

class AnimalList(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    list = models.ManyToManyField(Amimal)

我想将同一个口袋妖怪添加到同一个列表中两次:

>>> animal = Animal.objects.create(name='milla')
>>> user = User.objects.create(username='user')
>>> list = AnimalList.objects.create(user=user)
>>> list.list.add(animal)
>>> list.list.add(animal)
>>> animal.save()

但是,该动物仅添加一次:

>>> list.list.all()
<QuerySet [<Animal: Animal object (3)>]>

我希望,文档是明确的

添加第二次就可以了,它不会复制关系:

然而,我确实想重复这些动物。

我怎么能那样做?可以通过使用ManyToManyField吗?

标签: pythondjangomany-to-many

解决方案


我无法重复这些关系,因为 Django 将 a 应用于UniqueConstrant多对多关系。我的解决方案是添加另一个引用动物的表:

class AnimalListItem(models.Model):
    animal = models.ForeignKey(Animal, on_delete=models.CASCADE)

class AnimalList(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    list_items1 = models.ManyToManyField(AnimalListItem)

之后,每次我想将动物添加到列表中时,我都必须先创建一个列表项,指向该动物,然后将此列表项添加到列表列中。

还有其他可能的解决方案。例如,through参数fromManyToManyField禁用将添加到关系表中的任何默认约束。或者你可以设置db_constraintFalsewithout through

但是,这些对我来说不是解决方案,因为正如文档所述

如果中间模型定义的自定义直通表不对 (model1, model2) 对强制唯一性,允许多个值,则 remove() 调用将删除所有中间模型实例

我一次只需要删除一个实例,因此删除所有实例是不可行的。


推荐阅读