如何用django-rules替代guardian的PermissionListMixin实现用户仅查看自有地点
Django 用 django-rules 实现用户专属地点列表功能
1. 基础环境配置
- 安装依赖:
pip install django-rules - 配置
settings.py:
INSTALLED_APPS = [ # 其他原有应用 'rules', ] AUTHENTICATION_BACKENDS = [ 'django.contrib.auth.backends.ModelBackend', # 保留Django默认认证后端 'rules.permissions.ObjectPermissionBackend', # 新增django-rules对象权限后端 ]
2. 定义对象权限规则
在 Location 模型所属的应用目录下新建 rules.py 文件,写入如下逻辑:
import rules from .models import Location # 定义权限谓词:校验用户是否为地点所有者 @rules.predicate def is_location_owner(user, location): return user.is_authenticated and location.owner == user # 绑定视图权限:仅所有者可以查看对应地点 # 请将下方your_app_label替换为你实际的应用标识 rules.add_perm('your_app_label.view_location', is_location_owner)
3. 重写列表视图逻辑
django-rules 没有内置和 django-guardian PermissionListMixin 完全等效的自动过滤查询集工具,我们可以通过重写 get_queryset 方法实现相同效果:
from django.views import generic from .models import Location class LocationListView(generic.ListView): model = Location paginate_by = 20 ordering = ['name'] def get_queryset(self): # 仅返回当前登录用户拥有的地点,和权限规则逻辑保持一致 return super().get_queryset().filter(owner=self.request.user)
如果需要保留原有的权限校验逻辑,可继承 django-rules 提供的权限校验Mixin,代码如下:
from django.views import generic from rules.contrib.views import PermissionRequiredMixin from .models import Location class LocationListView(PermissionRequiredMixin, generic.ListView): model = Location # 替换为实际的应用标识 permission_required = 'your_app_label.view_location' paginate_by = 20 ordering = ['name'] def get_queryset(self): return super().get_queryset().filter(owner=self.request.user)
提示:如果你的权限规则更复杂,不只是判断所有者,小数据量场景下也可以封装通用的列表过滤Mixin,通过
perm函数遍历过滤有权限的对象;大数据量场景建议直接通过数据库查询条件过滤,执行效率更高。
内容的提问来源于stack exchange,提问作者gldecurtins
相关产品推荐
相关产品推荐

