如何在Django Admin中设置对象列表为只读,仅允许选择?
这个需求我之前在项目里刚好实现过,给你几个实用的方案,看哪种更适合你的场景:
方案1:自定义只读权限(最灵活)
这种方式适合需要给不同用户分配不同只读权限的场景,步骤如下:
- 给模型添加自定义只读权限
在你的模型models.py里,通过Meta类新增一个专属的只读权限:
class YourModel(models.Model): name = models.CharField(max_length=100) # 其他字段... class Meta: permissions = [ ("view_yourmodel_only", "仅查看YourModel,不能修改"), ]
添加完后记得执行python manage.py migrate,让Django把这个权限同步到数据库。
- 在Admin中控制权限和界面
在admin.py的ModelAdmin类里,重写几个权限方法,同时隐藏编辑入口:
from django.contrib import admin from .models import YourModel class YourModelAdmin(admin.ModelAdmin): list_display = ('name',) # 只展示你需要的字段 # 禁用修改权限 def has_change_permission(self, request, obj=None): if request.user.has_perm('your_app.view_yourmodel_only'): return False return super().has_change_permission(request, obj) # 禁用删除权限 def has_delete_permission(self, request, obj=None): if request.user.has_perm('your_app.view_yourmodel_only'): return False return super().has_delete_permission(request, obj) # 禁用添加权限 def has_add_permission(self, request): if request.user.has_perm('your_app.view_yourmodel_only'): return False return super().has_add_permission(request) # 隐藏列表中的编辑链接(不让用户点进修改页) def get_list_display_links(self, request, list_display): if request.user.has_perm('your_app.view_yourmodel_only'): return None return super().get_list_display_links(request, list_display) # 额外保障:如果用户通过URL直接进入修改页,强制所有字段只读 def get_readonly_fields(self, request, obj=None): if request.user.has_perm('your_app.view_yourmodel_only'): return [field.name for field in self.model._meta.fields] return super().get_readonly_fields(request, obj) admin.site.register(YourModel, YourModelAdmin)
之后你就可以在Django Admin的用户权限管理里,给目标用户分配这个仅查看YourModel的权限,他们就只能看列表、选择对象,完全碰不到修改/删除/添加的功能。
方案2:基于用户组的权限控制
如果你的只读用户都属于同一个用户组(比如叫“只读用户组”),可以直接通过组来判断,不用自定义权限:
class YourModelAdmin(admin.ModelAdmin): list_display = ('name',) def has_change_permission(self, request, obj=None): # 检查用户是否在只读组里 if request.user.groups.filter(name='只读用户组').exists(): return False return super().has_change_permission(request, obj) # 同样复制has_delete_permission、has_add_permission、get_list_display_links的逻辑 # ...
这种方式更简单,适合用户分组明确的场景。
方案3:极简版(快速实现)
如果只是临时需要某个Admin变成只读,不想搞权限,可以直接硬编码禁用所有修改相关功能:
class YourModelAdmin(admin.ModelAdmin): list_display = ('name',) list_display_links = None # 隐藏编辑链接 readonly_fields = [field.name for field in YourModel._meta.fields] def has_change_permission(self, request, obj=None): return False def has_delete_permission(self, request, obj=None): return False def has_add_permission(self, request): return False
这种方式适合测试或者小范围临时使用,不适合多用户权限区分的场景。
内容的提问来源于stack exchange,提问作者Hervé
相关产品推荐
相关产品推荐

