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

时间:2016-07-28 18:34:03

标签: django django-models many-to-many django-rest-framework django-signals

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

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

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

如果第一个User想要删除Item,则另一个User不会感到高兴 - 它需要保留,但最初显示为{{1} }}。但是,如果只有一个User仍然与之相关,那么User可以安全删除,应该删除以避免使用死记录填充数据库。

我认为应该如何处理:

  1. ItemItem delete
  2. 调用API
  3. User Item会检查pre_delete
  4. 如果item.user_set > 1,请手动删除True,将UserItem保留在原来的位置。如果Item,请删除False
  5. 这种方式Item不会通过API公开,并且简化了客户端的管理。

    这是正确/常见的方式吗?如何用Django完成?我不确定如何在UserItem内阻止Item.delete()发生pre_delete而不引发异常,但由于这是预期的行为,因此提出异常并不是正确的做法。

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

django docs:“如果您想要自定义删除行为,可以覆盖delete()方法。”

我认为这就是你想要的:

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

答案 2 :(得分:0)

这就是我的用途。它将逻辑保留在model中,但view为其提供当前user

我认为最好不要使用delete()因为管理员用户应该能够删除项目而不管相关用户,并且没有简单的方法来访问user内的delete() 1}}。

建设性批评欢迎!

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)