【问题标题】:How can I remove an object from a many to many for a queryset without iteration?如何在不迭代的情况下从多对多的查询集中删除一个对象?
【发布时间】:2017-06-27 21:19:39
【问题描述】:

在 Django 中,两个模型之间存在多对多关系。

我想从几个 model_two 实例中删除一个 model_one 实例。

我有:

user = User.objects.get(id=user_id)
conversations = Conversation.objects.filter(users=user)
for conversation in conversations.iterator():
    conversation.users.remove(user)

这需要评估对话的每一个实例。有没有办法在不迭代的情况下做到这一点?

更新:

添加模型以增加问题的清晰度。

class User(EditMixin):
    conversations = models.ManyToManyField('Conversation', related_name='users')
    name = models.CharField(max_length=255, blank=True, null=True)
    permalink = models.URLField(blank=True, max_length=2083)
    rating = models.DecimalField(decimal_places=2, max_digits=4, blank=True, default=0)
    remote_id = models.CharField(max_length=4096, blank=True, null=True)
    summary = models.CharField(max_length=255, blank=True, null=True)

    objects = UserManager()

class Meta:
    verbose_name_plural = 'Users'


class Conversation(EditMixin, BasicInfoMixin):
    content = models.TextField(blank=True, null=True)
    update_enabled = models.BooleanField(default=False)

    objects = ConversationManager()

class Meta:
    verbose_name_plural = 'Conversations'

更新 2:

我认为我的问题不清楚。 clear() 方法删除 m2m 字段中的所有项目。我想做的是:

我有一个用户对象的查询集。每个都有一个带有对话的 m2m 字段。查询集中的每个项目在 m2m 字段中都有对话 7,但也包含其他对话。我只想从查询集中每个对象的 m2m 中删除对话 7,同时保留其他对话。所有这些,如果可能,无需迭代,例如

之前:

Jeremy.conversations: [1, 2, 3, 4, 7]

Tiffany.conversations: [3, 7, 9]

Jeff.conversations: [5, 6, 7]

之后:

Jeremy.conversations: [1, 2, 3, 4]

Tiffany.conversations: [3, 9]

Jeff.conversations: [5, 6]

【问题讨论】:

    标签: django django-models many-to-many


    【解决方案1】:

    你可以使用这样的东西

    user = User.objects.get(id=user_id)
    user.conversation_set.clear()
    

    如果它从另一端多对多(编辑后适用于您的解决方案)

    user.conversations.clear()
    

    然后你可以在 remove 中有多个元素作为 args

    user.conversations.remove(*conversations)
    

    或使用 .through 访问数据透视表并从中删除

    【讨论】:

    • 你能输入你的模型定义吗
    • 这是 Django 中多对多关系的另一端,所以你应该使用以下
    • 几乎,但你让我得到了正确的答案。太感谢了!如果你把它写成conversation.users.remove(*users),它会给我我想要的
    猜你喜欢
    • 2015-09-17
    • 1970-01-01
    • 2011-05-06
    • 2017-02-07
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多