You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django Admin中设置对象列表为只读,仅允许选择?

这个需求我之前在项目里刚好实现过,给你几个实用的方案,看哪种更适合你的场景:

方案1:自定义只读权限(最灵活)

这种方式适合需要给不同用户分配不同只读权限的场景,步骤如下:

  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把这个权限同步到数据库。

  1. 在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é

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:19:54