首页 > 解决方案 > 限制对 Django 中对象的访问

问题描述

我有一个特定的模型,并且该模型具有细粒度的访问设置。就像是:

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

组由特定标签组成,这些标签链接到用户。长话短说,文档只能由特定用户访问。非常重要的是,这张支票不会从裂缝中溜走。所以我可以看到很多选项。一个是每次访问文档时,我都会添加检查:

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

但是有两个缺点:a)我在视图中查询文档模型 > 100 次,所以我会有很多重复的代码,b)很可能有人会在某些时候忘记添加这个限制,留下文档裸露。

所以我认为通过自定义管理器覆盖 objects() 是最有意义的。这样我就不会重复代码,也不会冒险忘记这样做。

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()

但是,问题在于那里无法访问请求:

名称“请求”未定义

如何解决这个问题?还是有更好的解决方案?

标签: djangodjango-models

解决方案


创建一个你的视图继承自的 mixin。这将防止到处都有重复的代码。您需要编写单元测试以确保您的视图被适当地锁定。

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):
    ...

推荐阅读