【问题标题】:Django Rest update many to many field of multiple objects at onceDjango Rest 一次更新多个对象的多对多字段
【发布时间】:2021-04-04 14:09:44
【问题描述】:

我正在开发聊天应用程序 django rest 后端。顺便说一句,我一次更新多个对象的 m2m 字段时遇到问题。 在Message 模型内部有一个m2m 字段deleted,它表示删除此消息的用户列表。

class Message(models.Model):
    # other fields  
    deleted = models.ManyToManyField(User)

因此,当用户删除特定消息时,我可以通过在该字段中添加用户来实现删除功能。 但问题是当用户删除一个对话(其中的所有消息)时,我如何实现一次更新多个Message 对象的delete 字段。因为每个对象都有空的delete字段,delete字段中的另一个用户,或者delete字段中的相同用户(意味着该用户之前已经删除了一条消息)。

编辑

根据validname的评论,我正在添加一个示例来说明我的问题。

请想象 user1 和 user2 有会话 1,并且该会话中有 3 条消息。所以目前该对话的消息列表如下:

[
  {
    id: 304,
    conversation: 1,
    ...
    deleted: []
  },
  {
    id: 305,
    conversation: 1,
    ...
    deleted: [2] // user2 already deleted this message before
  },
  {
    id: 306,
    conversation: 1,
    ...
    deleted: [1] // user1 already deleted this message before
  },
]

而 user2 刚刚删除了 conversation1,所以在该消息列表之后应该如下所示:

[
  {
    id: 304,
    conversation: 1,
    ...
    deleted: [2]
  },
  {
    id: 305,
    conversation: 1,
    ...
    deleted: [2] // no need to change for existing user2
  },
  {
    id: 306,
    conversation: 1,
    ...
    deleted: [1, 2] // insert user2
  },
]

我只想要一个与上述更改类似的 django 函数。

【问题讨论】:

  • 那么您是否遇到了在对话中查找所有消息或只是将它们添加到删除列表中的麻烦,您尝试做什么
  • 我只是在一个查询集中添加删除所有消息列表时遇到问题
  • 那么,再一次,你有一个消息查询集和一些用户,你想把这个用户添加到每条消息的“删除”中吗?对吗?
  • 你是对的,顺便说一句,问题只是在每个消息对象中保存 deleted 字段的旧值。例如,在user1和user2的会话中,有3条消息。旧的 deleted 字段只是 []、[1] 和 [2]。如果 user2 刚刚删除了对话,我想获得 [2]、[1,2] 和 [2] 的值。希望这个例子对你的理解有所帮助
  • 我不明白“旧删除”是什么意思,这些条件可能看起来像单独的问题。我建议您编辑您的帖子并添加清晰的场景,例如“我有 X,我想要 Y”,因为我在之前的评论中解释了您的帖子。

标签: django django-rest-framework


【解决方案1】:

所有m2m关系都由额外的表实现,并有自己的模型,可以通过字段的thorough属性访问。

因此,如果您有一组消息,并且您想为每条消息添加用户到“已删除”,您可以通过为模型批量创建记录来实现:

from itertools import cycle

message_qs = ...  # Query set of message.
user = ...  # User model instance.

# Construct list of [(message_1, user), (message_2, user), ...] etc.
data = list(zip(message_qs, cycle(user)))

# Transform data to through model instances to pass to bulk create.
through_model = Message.deleted.through
instances = [
    through_model(message=m, user=u) for m, u in data
]

through_model.objects.bulk_create(instances)

这应该是一种非常有效的方式。但是,如果您目前不关心效率,您可以遍历每个用户并为每个用户调用 message.deleted.add(user)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2011-02-05
    相关资源
    最近更新 更多