Detailed explanation of django Admin background management

You have just finished writing the Article, Category, and Tag models, but are you still worried about working overtime to manually add, delete, modify, check the background, and manage permissions? The Admin module that comes with django is simply the savior of Python back-end development✨. It can automatically generate a fully functional back-end interface based on your model, helping you save 80% of basic management development time.

In this article you will learn:

  • ✅ Quickly enable Admin and create administrators
  • ✅ Basic beautification and customization of list pages and form pages
  • ✅ Practical advanced functions such as batch operations and inline editing
  • ✅ Role-based permission control
  • ✅ Simple security reinforcement and appearance customization

Basic operations of django Admin

Enable Admin (enabled by default)

When django creates a new project, it is already in theINSTALLED_APPSAdded Admin related configuration, inurls.pyAlso reserved/admin/Entrance:

# settings.py(默认片段)
INSTALLED_APPS = [
    'django.contrib.admin',  # 核心Admin
    'django.contrib.auth',   # 用户认证
    'django.contrib.contenttypes',  # 模型关联
    # ... 其他应用
]

Create super administrator

The super administrator has all permissions of Admin and can create, modify, and delete any data and ordinary administrators:

python manage.py createsuperuser

💡 Tip: The email address can be left blank. The password must be at least 8 characters by default and cannot be too similar to the username.

After creation, start the servicepython manage.py runserver,accesshttp://127.0.0.1:8000/admin/You can log in.


Register the model to Admin

The default Admin interface will only displayUserandGroupFor the two models, to manage your own application data, you need toadmin.pyRegister in.

The simplest registration

# admin.py
from django.contrib import admin
from .models import Article  # 导入你的模型

admin.site.register(Article)

Refresh the background and you will see the entrance to the Article model. Click to enter and you can perform CRUD operations, but the interface will be very simple.

Use decorator@admin.register()combineadmin.ModelAdminSubcategory, you can quickly add list page display fields, search fields, filters, autofill, and other functions:

@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    list_display = ['name', 'slug', 'created_at']  # 列表页显示这些字段
    prepopulated_fields = {'slug': ('name',)}       # 自动根据name生成slug
    search_fields = ['name']                         # 添加搜索栏(按name搜索)
    list_filter = ['created_at']                     # 添加右侧时间过滤器

Admin commonly used custom functions

In-depth beautification of list page

The list page is the most commonly used page in the Admin backend. We can optimize it from various aspects such as sorting, paging, and operation buttons:

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    # 1. 核心显示字段
    list_display = [
        'title', 
        'author', 
        'category', 
        'formatted_status',  # 自定义字段(后续讲)
        'created_at', 
        'view_count'
    ]
    
    # 2. 每页显示20条(默认100条)
    list_per_page = 20
    
    # 3. 可点击进入详情页的字段(默认只有第一个)
    list_display_links = ['title', 'formatted_status']
    
    # 4. 可直接在列表页编辑的字段(无需进入详情页)
    list_editable = ['status']
    
    # 5. 右侧多条件过滤器
    list_filter = ['status', 'category', 'created_at', 'author']
    
    # 6. 顶部搜索栏(可跨模型搜索,比如author__username)
    search_fields = ['title', 'content', 'author__username']
    
    # 7. 顶部日期层级导航(快速按年/月/日筛选)
    date_hierarchy = 'created_at'
    
    # 8. 默认排序(按创建时间倒序)
    ordering = ['-created_at']

Customize list page fields (such as beautification status)

existModelAdminDefine a method in the subclass to display any calculated or beautified content on the list page:

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    # ... 前面的列表页配置 ...
    
    def formatted_status(self, obj):
        """给状态加颜色标签"""
        from django.utils.html import format_html
        
        status_colors = {
            'draft': 'orange',
            'published': 'green',
            'archived': 'gray'
        }
        color = status_colors.get(obj.status, 'black')
        
        # 用format_html生成安全的HTML
        return format_html(
            '<span style="color:{}; font-weight:bold;">{}</span>',
            color,
            obj.get_status_display()  # 获取choices的显示值
        )
    
    # 设置自定义字段的显示名称和排序依据
    formatted_status.short_description = '状态'
    formatted_status.admin_order_field = 'status'

Form page (details page) optimization

Field grouping and folding

If there are many model fields, you can usefieldsetsGrouping and even setting collapsible:

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    # ... 前面的配置 ...
    
    fieldsets = (
        ('基本信息', {
            'fields': ('title', 'author', 'category')
        }),
        ('文章内容', {
            'fields': ('content', 'summary'),
            'classes': ('wide',)  # 加宽字段
        }),
        ('发布设置', {
            'fields': ('status', 'tags', 'publish_date'),
            'classes': ('collapse',)  # 可折叠分组
        }),
        ('统计信息(只读)', {
            'fields': ('view_count', 'like_count'),
            'classes': ('collapse',)
        })
    )

Many-to-many field optimization

The default many-to-many field is a left and right selection box that is difficult to use. Usefilter_horizontalorfilter_verticalIt can be changed to the search + left and right drag style:

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    filter_horizontal = ['tags']  # 水平显示多对多
    # filter_vertical = ['tags']  # 垂直显示多对多

Practical advanced functions

Inline editing (one-to-many/many-to-many relationship)

If you want to directly edit its Comment (one-to-many) or ArticleCategory (many-to-many intermediate table) when editing an Article, you can useinline

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    # ... 前面的配置 ...
    
    # 1. 定义内联类(TabularInline是表格样式,StackedInline是堆叠样式)
    class CommentInline(admin.TabularInline):
        model = Comment
        extra = 0  # 不显示默认的空行
        readonly_fields = ['content', 'created_at', 'user']  # 只读字段
    
    # 2. 注册内联类
    inlines = [CommentInline]

Custom batch operations

The default batch operation is only "Delete Selected Items", we can add it ourselves, such as "Batch Publish" and "Batch Export CSV":

import csv
from django.http import HttpResponse
from django.contrib import messages

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    # ... 前面的配置 ...
    
    actions = ['make_published', 'export_csv']
    
    def make_published(self, request, queryset):
        """批量发布选中的文章"""
        updated = queryset.update(status='published')
        self.message_user(
            request,
            f'成功发布了 {updated} 篇文章!',
            messages.SUCCESS  # 显示绿色成功提示
        )
    
    make_published.short_description = "批量发布选中文章"
    
    def export_csv(self, request, queryset):
        """批量导出CSV"""
        response = HttpResponse(content_type='text/csv')
        response['Content-Disposition'] = 'attachment; filename="articles.csv"'
        
        writer = csv.writer(response)
        writer.writerow(['标题', '作者', '分类', '状态', '创建时间'])
        
        for article in queryset:
            writer.writerow([
                article.title,
                article.author.username,
                article.category.name if article.category else '未分类',
                article.get_status_display(),
                article.created_at.strftime('%Y-%m-%d %H:%M:%S')
            ])
        
        return response
    
    export_csv.short_description = "导出选中文章为CSV"

Simple permission control and security

Role-based permission control

Django Admin comes with its own permission system, we can passModelAdminMethods to dynamically control permissions:

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    # ... 前面的配置 ...
    
    def get_queryset(self, request):
        """普通用户只能看到自己的文章,超级用户能看到所有"""
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(author=request.user)
    
    def has_change_permission(self, request, obj=None):
        """普通用户只能修改自己的文章"""
        if request.user.is_superuser:
            return True
        if obj is None:  # 列表页不显示修改按钮
            return True
        return obj.author == request.user
    
    def save_model(self, request, obj, form, change):
        """新建文章时自动设置作者为当前用户"""
        if not change:
            obj.author = request.user
        super().save_model(request, obj, form, change)

Security reinforcement

  1. Modify the default Admin URL: prevent hackers from scanning/admin/
    # urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('my-secret-admin/', admin.site.urls),  # 改成复杂的路径
        # ... 其他URL
    ]
  2. Customized site header: Make the backend more like your own product
    # admin.py
    admin.site.site_header = '我的个人博客后台'
    admin.site.site_title = '博客管理'
    admin.site.index_title = '欢迎回来!'

Summarize

Although django Admin is not omnipotent (complex management functions still need to be developed by yourself), it is definitely the best choice for quickly verifying product prototypes and managing basic website data.

Today we only talked about the core functions of Admin. If you are interested, you can continue to explore customizing Admin views, replacing Admin templates, and integrating third-party Admin themes (such asdjango-grappelli) and other contents.

💡 Final reminder: Do not expose Admin to ordinary users, it is an internal tool for website operators or content editors!