通过 REST 在 Django 中删除 m2m 关系而不是对象本身 API
Deleting the m2m relationship instead of the the object itself in Django via REST API
我有 3 个模型:User
、UserItem
(m2m through)和 Item
。
一个User
可以创建一个Item
。这会自动创建一个 UserItem
.
另一个 User
可以看到 Item
,并将其添加到自己的项目列表中,创建另一个 UserItem
。
如果第一个 User
想要删除 Item
,另一个 User
不会高兴 - 它需要留下来,但对于最初的 [=11] 来说似乎已经消失了=].但是,如果只有一个 User
仍然与之相关,那么删除 Item
是安全的,应该删除以避免用死记录填满数据库。
我认为应该这样处理:
Item delete
从 User
调用 API
Item
pre_delete
检查是否 item.user_set > 1
- 如果
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)
我有 3 个模型:User
、UserItem
(m2m through)和 Item
。
一个User
可以创建一个Item
。这会自动创建一个 UserItem
.
另一个 User
可以看到 Item
,并将其添加到自己的项目列表中,创建另一个 UserItem
。
如果第一个 User
想要删除 Item
,另一个 User
不会高兴 - 它需要留下来,但对于最初的 [=11] 来说似乎已经消失了=].但是,如果只有一个 User
仍然与之相关,那么删除 Item
是安全的,应该删除以避免用死记录填满数据库。
我认为应该这样处理:
Item delete
从User
调用 API
Item
pre_delete
检查是否item.user_set > 1
- 如果
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)