django admin 后台管理
2025年2月17日大约 3 分钟约 822 字
基础配置
- 配置后台标题
conf/urls.py
from django.views.generic.base import RedirectView
from django.contrib import admin
admin.site.site_title = '标签页标题'
admin.site.site_header = '登录页和首页标题'
urlpatterns = [
    path('', RedirectView.as_view(url='/admin/', permanent=True)),  # 将根URL重定向到admin界面
    path('admin/', admin.site.urls),
    # ...- 配置app中文名称
xxxapp/apps.py
from django.apps import AppConfig
class DrawingappConfig(AppConfig):
    default_auto_field = "django.db.models.BigAutoField"
    name = "app_name"
    verbose_name = 'app中文名称'  # 这个属性中配置app中文名称重新注册用户模型
from django.contrib import admin
from django.contrib.auth.hashers import make_password
from django.contrib import messages
from django.contrib.auth.models import AbstractUser, Group, Permission, User
admin.site.unregister(User)
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    list_display_links = ('username',)
    search_fields = ('username', 'first_name')
    def get_list_display(self, request):
        """列表页展示的字段,管理员添加可见字段"""
        list_display = ('username', 'first_name', 'area', 'is_staff', 'is_superuser_display', 'date_joined', 'last_login')
        return list_display
    # 自定义显示字段
    @admin.display(description='超级管理员')
    def is_superuser_display(self, obj):
        return '是' if obj.is_superuser else ''
    # 列表过滤器功能的字段
    def get_list_filter(self, request):
        if request.user.is_superuser:
            list_filter = ('area',)
            self.list_filter_multiples = ('area',)
            return list_filter
        else:
            return super().get_list_filter(request)
    def get_fieldsets(self, request, obj=None):
        """详情页字段"""
        self.filter_horizontal = ['user_permissions', 'groups']
        fieldsets = [
            ("账号信息", {"fields": [('username', 'password', 'first_name', 'email')]}),
            ("登录权限", {"fields": ['area', 'is_staff', 'is_superuser']}),
            ("使用权限", {"fields": ['user_permissions', 'groups'], "classes": ['collapse']}),
        ]
        return fieldsets
    def get_changeform_initial_data(self, request):
        """详情页中初始值的修改"""
        initial = super().get_changeform_initial_data(request)
        initial['is_staff'] = True
        return initial
    def save_model(self, request, obj, form, change):
        """创建或修改某条数据的功能"""
        if obj.is_superuser:  # 如果是超管,无需配置区域
            obj.area = None
            
        if change:
            # 修改密码
            if obj.password != User.objects.get(pk=obj.pk).password:  # 如果有修改密码行为
                if obj.pk != request.user.pk and request.user.is_superuser is False:  # 如果不是超管,不可以修改其他人密码
                    messages.error(request, '您不是超管,不能修改其他人密码。')
                    return
                obj.password = make_password(obj.password)
        else:  # 如果是创建用户
            obj.password = make_password(obj.password)
        super().save_model(request, obj, form, change)
    def delete_model(self, request, obj):
        """删除时做一些处理"""
        obj.delete()
    def save_related(self, request, form, formsets, change):
        """保存外键和多对多关系数据"""
        super().save_related(request, form, formsets, change)
        obj = form.instance
        # 默认权限(必须先添加数据才能修改权限)
        if not change:  # 如果是新建用户
            if not obj.user_permissions.exists() and not obj.groups.exists():  # 如果没有手动添加权限
                permissions = Permission.objects.filter(content_type__app_label__in=['children', 'women', 'users'])
                obj.user_permissions.add(*permissions)
                user_permissions = Permission.objects.filter(content_type__app_label='auth', content_type__model='user')  # 用户表权限
                obj.user_permissions.add(*user_permissions)
    def get_queryset(self, request):
        """列表页的查询集"""
        qs = super().get_queryset(request)
        if not request.user.is_superuser:
            qs = qs.filter(area=request.user.area, is_superuser=False)
        return qs注册日志模型
from django.contrib import admin
from django.contrib.admin.models import LogEntry
# LogEntry._meta.app_label = 'auth'
@admin.register(LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
    """修改日志"""
    list_display = ('user', 'action_time', 'content_type', 'object_repr', 'action_flag', 'change_message')
    list_filter = ('action_flag', 'content_type', 'user')
    search_fields = ('object_repr', 'change_message', 'user__username')
    def get_queryset(self, request):
        # 为了优化性能,只选择必要的字段
        return super().get_queryset(request).select_related('user', 'content_type')
    def has_add_permission(self, request):
        """禁用添加权限"""
        return False
        
    def has_change_permission(self, request, obj=None):
        """禁用修改权限"""
        return True if request.user.is_superuser else False
    def has_delete_permission(self, request, obj=None):
        """禁用删除权限"""
        return False修改详情页字段的默认控件
@admin.register(ShortArticleModel)
class ShortArticleAdmin(admin.ModelAdmin):
    """将content字段的控件修改为Textarea"""
    # 其他代码...
    fieldsets = [
        (None, {"fields": ['title', 'content', 'tag']}),
        ("图片素材补充", {"fields": [('image1', 'image2', 'image3', 'image4', 'image5', 'image6', 'image7', 'image8', 'image9'), ], "classes": ['collapse']}),
    ]
    # 方法一:权重低
    # 修改content的widget为多行文本框
    class ShortArticleAdminForm(forms.ModelForm):
        class Meta:
            model = ShortArticleModel
            fields = '__all__'
            widgets = {
                'content': forms.Textarea(attrs={'rows': 10, 'cols': 100}),
            }
    form = ShortArticleAdminForm
    # 方法二:权重中
    def formfield_for_dbfield(self, db_field, request, **kwargs):
        if db_field.name == 'content':
            kwargs['widget'] = forms.Textarea(attrs={'rows': 10, 'cols': 100})
        return super().formfield_for_dbfield(db_field, request, **kwargs)
    # 方法三:权重高
    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.base_fields['content'].widget = forms.Textarea(attrs={'rows': 10, 'cols': 100})
        return form