You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Django/doc/djangoblog/logentryadmin.py

113 lines
4.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from django.contrib import admin
from django.contrib.admin.models import DELETION
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse, NoReverseMatch
from django.utils.encoding import force_str
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
class LogEntryAdmin(admin.ModelAdmin):
"""Django管理员日志条目的自定义管理界面"""
# 列表页过滤器配置:按内容类型过滤
list_filter = [
'content_type'
]
# 搜索字段配置:可按对象表示和变更消息搜索
search_fields = [
'object_repr',
'change_message'
]
# 列表页中可点击的链接字段
list_display_links = [
'action_time',
'get_change_message',
]
# 列表页显示的字段
list_display = [
'action_time', # 操作时间
'user_link', # 用户链接(自定义)
'content_type', # 内容类型
'object_link', # 对象链接(自定义)
'get_change_message', # 变更消息
]
def has_add_permission(self, request):
"""禁止添加新的日志条目"""
return False
def has_change_permission(self, request, obj=None):
"""修改权限控制只允许超级用户或具有特定权限的用户查看不允许POST修改"""
return (
request.user.is_superuser or
request.user.has_perm('admin.change_logentry')
) and request.method != 'POST'
def has_delete_permission(self, request, obj=None):
"""禁止删除日志条目"""
return False
def object_link(self, obj):
"""生成对象链接的显示"""
object_link = escape(obj.object_repr) # 转义对象表示字符串
content_type = obj.content_type
# 如果不是删除操作且内容类型存在,尝试生成可点击的链接
if obj.action_flag != DELETION and content_type is not None:
try:
# 构建管理员修改页面的URL
url = reverse(
'admin:{}_{}_change'.format(content_type.app_label,
content_type.model),
args=[obj.object_id]
)
# 创建HTML链接
object_link = '<a href="{}">{}</a>'.format(url, object_link)
except NoReverseMatch:
# 如果无法生成URL保持原样
pass
return mark_safe(object_link) # 标记为安全HTML
# 设置对象链接字段的排序和显示名称
object_link.admin_order_field = 'object_repr'
object_link.short_description = _('object')
def user_link(self, obj):
"""生成用户链接的显示"""
content_type = ContentType.objects.get_for_model(type(obj.user))
user_link = escape(force_str(obj.user)) # 转义用户字符串
try:
# 构建用户修改页面的URL
url = reverse(
'admin:{}_{}_change'.format(content_type.app_label,
content_type.model),
args=[obj.user.pk]
)
# 创建HTML链接
user_link = '<a href="{}">{}</a>'.format(url, user_link)
except NoReverseMatch:
# 如果无法生成URL保持原样
pass
return mark_safe(user_link) # 标记为安全HTML
# 设置用户链接字段的排序和显示名称
user_link.admin_order_field = 'user'
user_link.short_description = _('user')
def get_queryset(self, request):
"""获取查询集预取content_type关系以提高性能"""
queryset = super(LogEntryAdmin, self).get_queryset(request)
return queryset.prefetch_related('content_type')
def get_actions(self, request):
"""获取可用的批量操作,移除删除选中操作"""
actions = super(LogEntryAdmin, self).get_actions(request)
if 'delete_selected' in actions:
del actions['delete_selected'] # 移除批量删除选项
return actions