Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django:防止编辑/删除对象的更干燥的方法?_Python_Django_Django Views_Tastypie - Fatal编程技术网

Python Django:防止编辑/删除对象的更干燥的方法?

Python Django:防止编辑/删除对象的更干燥的方法?,python,django,django-views,tastypie,Python,Django,Django Views,Tastypie,在阅读了permission 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

在阅读了permission 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 !")
    #...
但我认为这并不干净和干燥,原因有二:

  • 在每个editStuff和deleteStuff视图中,我必须编写相同的代码部分

  • 我目前正在用Tastypie编写一个API,如果权限逻辑在视图中,我将无法重用它。最好的处理方法似乎是将API权限映射到Django权限(但我在视图中编写的代码与权限无关)

  • 你能帮我找到正确的方法吗?
    非常感谢。

    将附加参数传递到
    获取对象或404

    reward = get_object_or_404(Reward, pk=reward_id, owner=request.user)
    

    这是我的工作示例

    1) QuerySet

    2) 管理者

    3) 模型

    这种方法适用于基于类的视图。我看到你在用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中实现这一点很容易。

    我比Django更熟悉Rails,因此我无法给出特定于领域的答案,但您应该将该逻辑转移到您的模型中
    Reward
    会有一个类方法
    delete\u,如果你拥有的话
    或者你有什么。我同意这一点,但这并不妨碍我在所有想要删除的模型中编写这个方法。API呢?智能简单,thx。但即使编写起来更容易,这仍然不能解决API的“问题”。也许我的问题没有特别的解决方案。API问题是指重用吗?是的。我实际上为我在Tastypie中拥有的每个资源创建了自定义授权。这并不干燥,但这可能是唯一的方法。
    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)
    
    class MyModel(models.Model):
        ...
        objects = PermissionManager()
    
    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