首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django queryset权限

Django queryset权限
EN

Stack Overflow用户
提问于 2018-05-18 15:31:53
回答 4查看 5.8K关注 0票数 6

我正在构建一个非常复杂的Django应用程序,可以在电子邮件扫描服务之上使用。Django应用程序是使用Python 3.5+编写的。

此应用程序主要使用Django Rest Framework处理与浏览器中的前端的通信。

我目前面临的问题是,我试图实现System AdministratorDomain AdministratorApplication User的概念。

System Administrator基本上是“正常”的django superuser,因此能够执行所有的操作并查看系统中的每条记录。

Domain Administrator是管理一个或多个email domains的用户。我使用Many2Manyusers之间的关系来跟踪这一点。然后,我们的想法是预先定义一个过滤器,以便自动过滤处理的消息日志,仅显示指定给sender domaindomains列表中的domaindomains等于domains的消息。

blacklisting/whitelisting策略也是如此。

如果没有将Domain Administrator分配给任何domains,则不会显示任何数据。

Application User基本上是任何经过身份验证的用户,分配给他们一个或多个domains,使用与Domain Administrator相同的Many2Many关系。如果没有指定域,则不会显示任何数据。

我在这里找到了一些关于使request.userQuerySetModelManager中可用的其他解决方案,但这似乎不是正确的处理方法。

我看过django-guardiandjango-authoritydjango-permissions,但它们似乎都没有影响到QuerySet或由此产生的对象列表。

是否有人对Django包/addon有一个可以用来处理这个问题的建议,或者对于如何处理这个问题有一个想法?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-05-18 18:02:06

DRF的GenericAPIView有一个可以重写以执行自定义筛选的get_queryset方法:

代码语言:javascript
复制
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文档字符串建议重写以下内容:

如果您需要根据传入的请求提供不同的查询集,则可能需要重写该查询集。

票数 2
EN

Stack Overflow用户

发布于 2020-09-02 10:38:06

我是django-cancanhttps://github.com/pgorecki/django-cancan的作者,它致力于解决您所描述的确切问题。

原理如下:首先,确定每个用户的能力,然后在视图中,检查给定对象、模型的用户能力,或者根据这些能力检索查询集。

声明部分如下所示:

代码语言:javascript
复制
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)

然后,您可以在每个对象级别上检查是否有能力:

代码语言:javascript
复制
def article_detail_view(request, pk):
    article = Article.objects.get(pk=pk)
    if request.ability.can('view', article):
        ...

或者在模型层面上:

代码语言:javascript
复制
def article_create_view(request, pk):
    if request.ability.can('add', Article):
        ...

或者获取带有可访问对象的查询集:

代码语言:javascript
复制
def another_list_view(request, pk):
    articles = request.ability.queryset_for('view', Article)
    ...
票数 2
EN

Stack Overflow用户

发布于 2018-05-19 08:48:16

我想你误解了Django的许可概念。django-guardiandjango-authoritydjango-permissions --所有这些包都是用于在Django应用程序中处理权限的。permission所做的是检查模型的某些模型或实例,如果用户拥有查看特定模型或对象的权限,否则它将返回403 Unauthorized响应。权限不会更改或筛选查询集,只返回有效的结果。

相反,如果您想应用过滤器查询集,您可以通过上面的答案这样做,或者您可以将该代码移动到Mixin中以遵循DRY Style。对于Mixin参考,您可以看到以下链接:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50414750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档