Django:更干燥的方法来防止编辑/删除对象?
我看完Django的权限文档后,还是有点困惑。
我想要防止用户编辑或删除他们不拥有的对象。
我这样做了,效果不错:
在views.py文件中:
def deleteReward(request, reward_id):
reward = get_object_or_404(Reward, pk=reward_id)
if reward.owner.user != request.user: # if the user linked to the reward is not the current one
raise Exception("This reward is not yours, you can't delete it !")
#...
但是我觉得这样不太干净,也不符合DRY原则,原因有两个:
在每个editStuff和deleteStuff的视图中,我都得写同样的代码。
我现在正在用Tastypie写一个API,如果权限逻辑放在视图里,我就不能重用它。看起来最好的解决办法是把API的权限和Django的权限对应起来(但我在视图中写的代码和权限没有关系)。
你能帮我找到正确的方法吗?非常感谢。
2 个回答
1
给 get_object_or_404
函数传递一个额外的参数:
reward = get_object_or_404(Reward, pk=reward_id, owner=request.user)
2
这是我的一个工作示例。
1) 查询集
class PermissionQuerySet(models.query.QuerySet):
def editable_by(self, user):
return self.filter(user=user)
def viewable_by(self, user):
return self.filter(user=user)
2) 管理器
class PermissionManager(models.Manager):
def get_query_set(self):
return PermissionQuerySet(self.model)
def editable_by(self, user, *args):
return self.get_query_set().editable_by(user, *args)
def viewable_by(self, user, *args):
return self.get_query_set().viewable_by(user, *args)
3) 模型
class MyModel(models.Model):
...
objects = PermissionManager()
这种方法在基于类的视图中效果很好。我看到你在使用TastyPie。我之前没用过它,但看起来它也使用基于类的视图。
这是一个工作示例:
class MyUpdateView(UpdateView):
def post(self, request, *args, **kwargs):
self.request = request
super(MyUpdateView, self).post(request, *args, **kwargs)
def get_query_set(self):
queryset = super(MyUpdateView, self).get_query_set()
queryset = queryset.editable_by(self.request.user)
if not queryset.exists():
raise Exception("This reward is not yours, you can't delete it !")
return queryset
我想你可以想象如何在CreateView和DeleteView中使用这种方法。我觉得在TastyPie中实现这个也很简单。