我正在构建一个非常复杂的Django应用程序,可以在电子邮件扫描服务之上使用。Django应用程序是使用Python 3.5+编写的。
此应用程序主要使用Django Rest Framework处理与浏览器中的前端的通信。
我目前面临的问题是,我试图实现System Administrator、Domain Administrator和Application User的概念。
System Administrator基本上是“正常”的django superuser,因此能够执行所有的操作并查看系统中的每条记录。
Domain Administrator是管理一个或多个email domains的用户。我使用Many2Many与users之间的关系来跟踪这一点。然后,我们的想法是预先定义一个过滤器,以便自动过滤处理的消息日志,仅显示指定给sender domain的domains列表中的domain或domains等于domains的消息。
blacklisting/whitelisting策略也是如此。
如果没有将Domain Administrator分配给任何domains,则不会显示任何数据。
Application User基本上是任何经过身份验证的用户,分配给他们一个或多个domains,使用与Domain Administrator相同的Many2Many关系。如果没有指定域,则不会显示任何数据。
我在这里找到了一些关于使request.user对QuerySet在ModelManager中可用的其他解决方案,但这似乎不是正确的处理方法。
我看过django-guardian、django-authority和django-permissions,但它们似乎都没有影响到QuerySet或由此产生的对象列表。
是否有人对Django包/addon有一个可以用来处理这个问题的建议,或者对于如何处理这个问题有一个想法?
发布于 2018-05-18 18:02:06
DRF的GenericAPIView有一个可以重写以执行自定义筛选的get_queryset方法:
def get_queryset(self):
qs = super(YourView, self).get_queryset()
return self.filter_queryset_for_user(qs, request.user)
def filter_queryset_for_user(self, qs, user):
pass # Your logic here这不一定是个坏主意;DRF文档字符串建议重写以下内容:
如果您需要根据传入的请求提供不同的查询集,则可能需要重写该查询集。
发布于 2020-09-02 10:38:06
我是django-cancan库https://github.com/pgorecki/django-cancan的作者,它致力于解决您所描述的确切问题。
原理如下:首先,确定每个用户的能力,然后在视图中,检查给定对象、模型的用户能力,或者根据这些能力检索查询集。
声明部分如下所示:
def declare_abilities(user, ability):
if not user.is_authenticated:
# Allow anonymous users to view only published articles
ability.can('view', Article, published=True)
else:
# logged in user can view any article...
ability.can('view', Article)
# ... and change his own
ability.can('change', Article, author=user)
# ... and add new ones
ability.can('add', Article)
if user.is_superuser:
# Allow superuser to view and change any article
ability.can('view', Article)
ability.can('change', Article)然后,您可以在每个对象级别上检查是否有能力:
def article_detail_view(request, pk):
article = Article.objects.get(pk=pk)
if request.ability.can('view', article):
...或者在模型层面上:
def article_create_view(request, pk):
if request.ability.can('add', Article):
...或者获取带有可访问对象的查询集:
def another_list_view(request, pk):
articles = request.ability.queryset_for('view', Article)
...发布于 2018-05-19 08:48:16
我想你误解了Django的许可概念。django-guardian、django-authority和django-permissions --所有这些包都是用于在Django应用程序中处理权限的。permission所做的是检查模型的某些模型或实例,如果用户拥有查看特定模型或对象的权限,否则它将返回403 Unauthorized响应。权限不会更改或筛选查询集,只返回有效的结果。
相反,如果您想应用过滤器查询集,您可以通过上面的答案这样做,或者您可以将该代码移动到Mixin中以遵循DRY Style。对于Mixin参考,您可以看到以下链接:
https://stackoverflow.com/questions/50414750
复制相似问题