如何为仅拥有查看权限的用户自定义Django Admin UI详情页显示
自定义Django Admin只读详情页的字段显示
针对仅拥有查看权限的用户,在Django Admin的变更详情页(URL以change结尾的只读页面),可以通过以下几种方式自定义字段显示:
1. 重写change_form_template自定义页面模板
你提到的change_form_template完全可以用来实现需求。步骤如下:
- 在你的应用下创建
admin/change_form.html模板,继承Django默认的admin/change_form.html - 在模板中找到只读字段的渲染区块(通常是
{% for field in adminform %}循环里的只读字段部分),针对无修改权限的用户做自定义调整:- 通过
{{ perms }}模板变量判断用户权限,比如{% if not perms.yourapp.change_yourmodel %} - 修改只读字段的HTML结构,比如给特定字段添加自定义CSS类、调整排版,甚至替换字段的显示内容
- 通过
示例模板片段:
{% extends "admin/change_form.html" %} {% block field_sets %} {% for fieldset in adminform %} {% include "admin/includes/fieldset.html" %} {% endfor %} {% if not perms.myapp.change_mymodel %} <!-- 给只读用户添加自定义样式 --> <style> .readonly { background-color: #f8f9fa; padding: 8px; border-radius: 4px; } </style> {% endif %} {% endblock %}
然后在ModelAdmin中指定模板:
class MyModelAdmin(admin.ModelAdmin): change_form_template = 'admin/change_form.html'
2. 使用formfield_for_readonly_field自定义单个字段显示
Django提供了formfield_for_readonly_field方法,允许为每个只读字段自定义渲染逻辑,返回的HTML字符串可完全控制字段的显示样式和内容。
示例代码:
from django.utils.safestring import mark_safe class MyModelAdmin(admin.ModelAdmin): def formfield_for_readonly_field(self, db_field, request, **kwargs): # 判断用户是否只有查看权限 if not request.user.has_perm('myapp.change_mymodel'): if db_field.name == 'created_at': # 自定义日期字段的显示格式和样式 value = kwargs['obj'].created_at return mark_safe(f'<span class="custom-date">{value.strftime("%Y年%m月%d日 %H:%M")}</span>') elif db_field.name == 'author': # 自定义外键字段的显示,比如添加头像 author = kwargs['obj'].author return mark_safe(f'<div class="author-info"><img src="{author.avatar.url}" class="avatar" />{author.username}</div>') # 默认返回原只读字段渲染 return super().formfield_for_readonly_field(db_field, request, **kwargs)
3. 动态调整只读字段列表与显示
通过get_readonly_fields方法,结合用户权限动态控制只读字段,甚至可以添加自定义"伪字段"展示额外内容:
from django.utils.safestring import mark_safe class MyModelAdmin(admin.ModelAdmin): def get_readonly_fields(self, request, obj=None): readonly_fields = super().get_readonly_fields(request, obj) if not request.user.has_perm('myapp.change_mymodel'): # 给只读用户添加自定义字段 readonly_fields += ('custom_field',) return readonly_fields def custom_field(self, obj): # 自定义字段的显示内容 return mark_safe(f'<div class="custom-content">额外展示:{obj.some_field}</div>') custom_field.short_description = '自定义内容'
你提到的"无法自定义只读字段"的说法,大概率是针对旧版本Django的限制,当前Django 4.2+版本完全支持上述方式实现自定义。
内容的提问来源于stack exchange,提问作者dfrankow
相关产品推荐
相关产品推荐

