django Admin后台管理详解
刚写完Article、Category、Tag模型,还在发愁加班加点手写增删改查后台、权限管理?django自带的Admin模块简直是Python后端开发的救星✨,它能基于你的模型自动生成功能完备的后台界面,帮你省下80%的基础管理开发时间。
本文你将学到:
- ✅ 快速启用Admin并创建管理员
- ✅ 列表页、表单页的基础美化与自定义
- ✅ 批量操作、内联编辑等实用高级功能
- ✅ 基于角色的权限控制
- ✅ 简单的安全加固与外观定制
django Admin 基础操作
启用Admin(默认已开启)
django新建项目时,默认已在 INSTALLED_APPS 加入了Admin相关配置,在 urls.py 也预留了 /admin/ 入口:
# settings.py(默认片段)
INSTALLED_APPS = [
'django.contrib.admin', # 核心Admin
'django.contrib.auth', # 用户认证
'django.contrib.contenttypes', # 模型关联
# ... 其他应用
]
创建超级管理员
超级管理员拥有Admin的全部权限,可以创建、修改、删除任何数据和普通管理员:
python manage.py createsuperuser
💡 提示:邮箱可以留空,密码默认要求至少8位,且不能与用户名太相似。
创建完成后,启动服务 python manage.py runserver,访问 http://127.0.0.1:8000/admin/ 即可登录。
注册模型到Admin
默认Admin界面只会显示 User 和 Group 两个模型,要管理自己的应用数据,需要在应用的 admin.py 中注册。
最简单的注册
# admin.py
from django.contrib import admin
from .models import Article # 导入你的模型
admin.site.register(Article)
刷新后台就能看到Article模型的入口,点击进入即可进行CRUD操作,但界面会非常朴素。
带基础配置的注册(推荐)
用装饰器 @admin.register() 结合 admin.ModelAdmin 子类,可以快速添加列表页显示字段、搜索栏、过滤器、自动填充等功能:
@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 常用自定义功能
列表页深度美化
列表页是Admin后台最常用的页面,我们可以从排序、分页、操作按钮等多方面优化:
@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']
自定义列表页字段(比如美化状态)
在 ModelAdmin 子类中定义一个方法,就能在列表页显示任何计算或美化后的内容:
@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'
表单页(详情页)优化
字段分组与折叠
如果模型字段很多,可以用 fieldsets 分组,甚至设置可折叠:
@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',)
})
)
多对多字段优化
默认多对多字段是一个很难用的左右选择框,用 filter_horizontal 或 filter_vertical 可以改成搜索+左右拖拽的样式:
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
filter_horizontal = ['tags'] # 水平显示多对多
# filter_vertical = ['tags'] # 垂直显示多对多
实用高级功能
内联编辑(一对多/多对多关系)
如果想在编辑Article时,直接编辑它的Comment(一对多)或ArticleCategory(多对多中间表),可以用 inline:
@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]
自定义批量操作
默认批量操作只有“删除选中项”,我们可以自己添加,比如“批量发布”“批量导出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"
简单的权限控制与安全
基于角色的权限控制
django Admin自带权限系统,我们可以通过 ModelAdmin 的方法动态控制权限:
@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)
安全加固
- 修改默认Admin URL:防止黑客扫描到
/admin/
# urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('my-secret-admin/', admin.site.urls), # 改成复杂的路径
# ... 其他URL
]
- 自定义站点头部:让后台更像自己的产品
# admin.py
admin.site.site_header = '我的个人博客后台'
admin.site.site_title = '博客管理'
admin.site.index_title = '欢迎回来!'
总结
django Admin虽然不是万能的(复杂的管理功能还是要自己开发),但对于快速验证产品原型、管理网站基础数据来说,绝对是不二之选。
今天我们只讲了Admin的核心功能,如果你感兴趣,可以继续探索自定义Admin视图、替换Admin模板、集成第三方Admin主题(比如 django-grappelli)等内容。
💡 最后提醒:不要把Admin暴露给普通用户,它是给网站运营者或内容编辑用的内部工具!