如何为Django对象创建者分配权限?管理员端编辑权限问题
在Django Admin中限制仅对象创建者可编辑的实现方案
当然可以实现仅对象创建者编辑对象的需求,而且完全不需要依赖django-guardian——原生Django就能高效搞定,下面分两种方案说明:
一、原生Django实现(推荐,无额外依赖)
这种方式不需要任何第三方库,通过模型字段和Admin类的方法重写就能完成,全程自动关联创建者,无需手动分配权限。
1. 给模型添加创建者字段
在你的模型中新增一个关联用户的字段,用来记录对象的创建者:
from django.db import models from django.contrib.auth.models import User class YourModel(models.Model): # 其他业务字段... created_by = models.ForeignKey( User, on_delete=models.CASCADE, editable=False, # 禁止在Admin中手动修改该字段 verbose_name="创建者" )
2. 重写Admin的save_model方法,自动设置创建者
当用户在Admin中创建新对象时,自动把当前登录用户赋值给created_by字段:
from django.contrib import admin from .models import YourModel class YourModelAdmin(admin.ModelAdmin): # 其他Admin配置(比如list_display等)... def save_model(self, request, obj, form, change): if not change: # 仅在创建新对象时执行 obj.created_by = request.user super().save_model(request, obj, form, change)
3. 限制用户只能看到自己创建的对象
重写get_queryset方法,让普通用户只能看到自己创建的内容,超级用户可以看到全部:
def get_queryset(self, request): queryset = super().get_queryset(request) if request.user.is_superuser: return queryset return queryset.filter(created_by=request.user)
4. 限制仅创建者/超级用户可编辑、删除对象
重写权限判断方法,确保只有对象创建者或超级用户拥有编辑、删除权限:
def has_change_permission(self, request, obj=None): # 如果是列表页(obj为None)返回默认权限;详情页则判断权限 if obj is None: return super().has_change_permission(request, obj) return request.user.is_superuser or obj.created_by == request.user def has_delete_permission(self, request, obj=None): if obj is None: return super().has_delete_permission(request, obj) return request.user.is_superuser or obj.created_by == request.user
二、使用django-guardian的优化方案(非必须)
如果你因为其他需求已经在用django-guardian,也可以实现自动分配权限,不需要手动操作:
1. 用信号自动分配对象权限
通过Django的post_save信号,在对象创建完成后,自动给创建者分配该对象的编辑、删除权限:
from django.db.models.signals import post_save from django.dispatch import receiver from guardian.shortcuts import assign_perm from .models import YourModel @receiver(post_save, sender=YourModel) def assign_object_permissions(sender, instance, created, **kwargs): if created: # 给创建者分配当前对象的change和delete权限 assign_perm('change_yourmodel', instance.created_by, instance) assign_perm('delete_yourmodel', instance.created_by, instance)
2. 继承GuardianModelAdmin
在Admin类中继承GuardianModelAdmin,它会自动处理对象级权限的展示和判断:
from guardian.admin import GuardianModelAdmin class YourModelAdmin(GuardianModelAdmin): # 其他Admin配置... pass
总结
- 实现仅创建者编辑的需求完全不需要django-guardian,原生方案更轻量、高效,没有额外依赖;
- 如果一定要用django-guardian,通过信号可以自动分配权限,无需手动操作,只是需要额外安装和配置依赖。
内容的提问来源于stack exchange,提问作者vei nen
相关产品推荐
相关产品推荐

