Django: more DRY way to prevent editing / deleting objects?

After reading the Django design documentation, I'm still confused. I would like the user to not be able to edit or delete objects that they did not have. I do it this way and it works:

In 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 !")
    #...

But I think it is not clean and dry for two reasons:

  • In each view of editStuff and deleteStuff, I have to write the same piece of code.

  • I am currently writing an API with Tastypie, and if the resolution logic is in the view, I cannot reuse it. It seems like the best way to handle displaying API permissions with Django permissions (but the code I wrote in my view has nothing to do with permissions).

Could you help me find the right way? Many thanks.

+4
2

.

1) QuerySet

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.

+2

get_object_or_404:

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

Source: https://habr.com/ru/post/1530069/


All Articles