Django如何按登录用户/所有者控制Model对象权限?
实现Django对象所有者权限控制的优雅方案
不需要在每个视图里手动编写重复的校验逻辑,以下是几种复用性强、更优雅的实现方式:
1. 自定义权限校验Mixin类
把所有者校验逻辑封装成Mixin,需要权限控制的视图直接继承即可,避免重复代码:
from django.contrib.auth.mixins import AccessMixin from django.http import HttpResponseForbidden class OwnerRequiredMixin(AccessMixin): def get_object(self, queryset=None): obj = super().get_object(queryset) if obj.creator != self.request.user: return self.handle_no_permission() return obj def handle_no_permission(self): return HttpResponseForbidden("你没有权限操作该对象")
在各类视图中使用:
# 详情视图 class MyModelDetailView(OwnerRequiredMixin, DetailView): model = MyModel # 更新视图 class MyModelUpdateView(OwnerRequiredMixin, UpdateView): model = MyModel fields = ['字段1', '字段2'] # 删除视图同理 class MyModelDeleteView(OwnerRequiredMixin, DeleteView): model = MyModel success_url = '/mymodel/list/'
针对列表视图,单独封装过滤Mixin,只返回当前用户的对象:
class OwnerListMixin: def get_queryset(self): return super().get_queryset().filter(creator=self.request.user) class MyModelListView(OwnerListMixin, ListView): model = MyModel
2. 自定义模型Manager(默认过滤当前用户数据)
如果希望所有对该模型的查询默认只返回当前用户的对象,可以自定义Manager:
class MyModelManager(models.Manager): def for_user(self, user): return self.filter(creator=user) class MyModel(models.Model): creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) objects = MyModelManager()
后续在视图或业务逻辑中,直接通过MyModel.objects.for_user(self.request.user)获取当前用户的对象集合,结合上面的Mixin使用能进一步简化逻辑。
3. 自动填充创建者(创建视图优化)
创建对象时自动将当前用户设为creator,无需手动处理:
class MyModelCreateView(CreateView): model = MyModel fields = ['字段1', '字段2'] def form_valid(self, form): form.instance.creator = self.request.user return super().form_valid(form)
内容的提问来源于stack exchange,提问作者andrew
相关产品推荐
相关产品推荐

