通过 REST 在 Django 中删除 m2m 关系而不是对象本身 API

Deleting the m2m relationship instead of the the object itself in Django via REST API

我有 3 个模型:UserUserItem(m2m through)和 Item

一个User可以创建一个Item。这会自动创建一个 UserItem.

另一个 User 可以看到 Item,并将其添加到自己的项目列表中,创建另一个 UserItem

如果第一个 User 想要删除 Item,另一个 User 不会高兴 - 它需要留下来,但对于最初的 [=11] 来说似乎已经消失了=].但是,如果只有一个 User 仍然与之相关,那么删除 Item 是安全的,应该删除以避免用死记录填满数据库。

我认为应该这样处理:

  1. Item deleteUser
  2. 调用 API
  3. Item pre_delete 检查是否 item.user_set > 1
  4. 如果True,手动删除UserItem,将Item留在原处。如果False,删除Item

这样 UserItem 不会通过 API 公开,并且简化了客户端的管理。

这是right/common的方法吗?用 Django 怎么办?我不确定如何在不引发异常的情况下防止 Item.delete()pre_delete 内发生,但正如预期的那样,引发异常的行为似乎不是执行此操作的正确方法。

我觉得这很好。但是,您可以不使用信号,而是覆盖 Item 模型上的 delete() 方法。有关 save() 方法的示例,请参阅 the official documentation。您的 delete() 方法可以同样实现,即当还有其他用户使用 UserItem 时,它不会调用 super()

来自 django docs:"If you want customized deletion behavior, you can override the delete() method."

我想这就是你想要的:

def delete(self, *args, **kwargs):
    if item.user_set > 1:
        return
    else:
        super(Item, self).delete(*args, **kwargs) # Call the "real" delete() method.

这是我的经历。它保留 model 中的逻辑,但 view 为它提供当前的 user.

我认为最好远离 delete() 因为管理员用户应该能够删除项目而不考虑相关用户,并且没有简单的方法来访问当前 user delete().

欢迎建设性批评!

models.py

class Item(TimeStampedModel):

    ...

    def delete_item_or_user_item(self, user):
    """
    Delete the Item if the current User is the only User related to it.
    If multiple Users are related to the Item, delete the UserItem.
    """
    if UserItem.objects.filter(item=self).count() > 1:
        UserItem.objects.filter(item=self, user=user).delete()
    else:
        self.delete()

views.py

class ItemViewSet(viewsets.ModelViewSet):

    ...

    def perform_destroy(self, instance):
        instance.delete_item_or_user_item(self.request.user)