Limiting access to objects in Django

柔情痞子 提交于 2021-01-29 17:49:57

问题


I have a particular model and that model has finegrained access settings. Something like:

class Document(models.Model):
    ...
    access = models.ManyToManyField(Group)

Groups consist of particular tags, and those tags are linked to users. Long story short, one way or another the documents are only accessible by particular users. It is very important that this check does not slip through the cracks. So I can see a number of options. One is that every time I access a Document, I add the check:

Document.objects.filter(access__group__tag__user=request.user)

But there are two drawbacks: a) I query the documents model > 100 times in my views so I will have a LOT of repeated code, and b) it's quite likely that someone will at some point forget to add this restriction in, leaving documents exposed.

So I am thinking that overwriting the objects() makes most sense, through a custom manager. That way I don't duplicate code and I don't risk forgetting to do this.

class HasAccessManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(access__group__tag__user=request.user)

class Document(models.Model):
    ...
    access = models.ManyToManyField(Group)
    objects = HasAccessManager()

However, the problem becomes that request is not accessible there:

name 'request' is not defined

How to solve this? Or are there better solutions?


回答1:


Create a mixin that your views inherit from. This will prevent having duplicated code everywhere. You'll want to write unit tests to make sure your views are locked down appropriately.

class HasAccessMixin(object):
    def get_queryset(self):
        qs = super().get_queryset()

        # you can still leverage a custom model manager here if you want
        # qs = qs.custom_method(access__group__tag__user=self.request.user)

        qs = queryset.filter(access__group__tag__user=self.request.user)
        return qs

class SomeListView(HasAccessMixin, ListView):
    ...

class SomeDetailView(HasAccessMixin, DetailView):
    ...


来源:https://stackoverflow.com/questions/58039448/limiting-access-to-objects-in-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!