django - 限制对 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()
但是,问题在于那里无法访问请求:
名称“请求”未定义
如何解决这个问题?还是有更好的解决方案?
解决方案
创建一个你的视图继承自的 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):
...
推荐阅读
- sql-server - 每天的 SQL 活跃用户数
- r - R用ifelse()条件改变多列
- windows - 我无法更改 Jupyter Notebook 启动文件夹(有限的“目标”字段“)
- android - Kotlin:空对象引用上的 getResources()
- apache-kafka - 带有状态存储的流式应用程序最多需要 1 小时才能重新启动
- c# - 如何在 Windows 窗体设计器中保存用户控件的结构属性?
- amazon-redshift - 胶水创建重复记录,如何解决?
- flutter - 范围模型中的 Sqflite
- php - PHP中双向链表元素的有效插入和/或删除
- python - Django 在数据库中更改错误的列名