第10章:Django管理后台
10.1 Admin基础
创建超级用户
Django管理后台是一个功能强大的CRUD界面,允许管理员用户管理网站内容。首先需要创建超级用户来访问管理后台:
bash
# 创建超级用户
python manage.py createsuperuser
# 按提示输入用户名、邮箱和密码
Username (leave blank to use 'yourname'): admin
Email address: admin@example.com
Password: ********
Password (again): ********
Superuser created successfully.通过编程方式创建超级用户:
python
# 在Django shell中创建超级用户
from django.contrib.auth.models import User
# 方法1:使用create_superuser方法
user = User.objects.create_superuser(
username='admin',
email='admin@example.com',
password='securepassword'
)
# 方法2:创建普通用户后设置超级用户权限
user = User.objects.create_user(
username='admin',
email='admin@example.com',
password='securepassword'
)
user.is_staff = True
user.is_superuser = True
user.save()在部署时自动创建超级用户:
python
# management/commands/create_admin.py
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User
import os
class Command(BaseCommand):
help = 'Create a superuser if it does not exist'
def handle(self, *args, **options):
username = os.environ.get('DJANGO_SUPERUSER_USERNAME', 'admin')
email = os.environ.get('DJANGO_SUPERUSER_EMAIL', 'admin@example.com')
password = os.environ.get('DJANGO_SUPERUSER_PASSWORD', 'admin')
if not User.objects.filter(username=username).exists():
User.objects.create_superuser(username, email, password)
self.stdout.write(
self.style.SUCCESS(f'Superuser {username} created successfully')
)
else:
self.stdout.write(
self.style.WARNING(f'Superuser {username} already exists')
)注册模型
要让模型在管理后台中可见,需要在应用的admin.py文件中注册模型:
python
# models.py
from django.db import models
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
description = models.TextField(blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = "分类"
verbose_name_plural = "分类"
def __str__(self):
return self.name
class Tag(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(unique=True)
class Meta:
verbose_name = "标签"
verbose_name_plural = "标签"
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
tags = models.ManyToManyField(Tag, blank=True)
content = models.TextField()
excerpt = models.TextField(blank=True)
is_published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = "文章"
verbose_name_plural = "文章"
ordering = ['-created_at']
def __str__(self):
return self.title
# admin.py
from django.contrib import admin
from .models import Category, Tag, Article
# 基本注册方式
admin.site.register(Category)
admin.site.register(Tag)
# 使用装饰器注册
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'author', 'category', 'is_published', 'created_at']
list_filter = ['is_published', 'category', 'created_at']
search_fields = ['title', 'content']
prepopulated_fields = {'slug': ('title',)}
date_hierarchy = 'created_at'Admin界面自定义
自定义管理后台界面以提高可用性:
python
# admin.py
from django.contrib import admin
from django.utils.html import format_html
from .models import Category, Tag, Article
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ['name', 'slug', 'article_count', 'created_at']
list_filter = ['created_at']
search_fields = ['name', 'description']
prepopulated_fields = {'slug': ('name',)}
ordering = ['name']
def article_count(self, obj):
return obj.article_set.count()
article_count.short_description = '文章数量'
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ['name', 'slug', 'article_count']
search_fields = ['name']
prepopulated_fields = {'slug': ('name',)}
def article_count(self, obj):
return obj.article_set.count()
article_count.short_description = '文章数量'
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
# 列表显示
list_display = [
'title', 'author', 'category', 'is_published',
'created_at', 'preview_link'
]
list_filter = ['is_published', 'category', 'tags', 'created_at', 'author']
search_fields = ['title', 'content', 'excerpt']
ordering = ['-created_at']
date_hierarchy = 'created_at'
# 编辑页面
fieldsets = (
('基本信息', {
'fields': ('title', 'slug', 'author', 'excerpt')
}),
('内容', {
'fields': ('content',),
'classes': ('wide',)
}),
('分类和标签', {
'fields': ('category', 'tags')
}),
('发布设置', {
'fields': ('is_published',),
'classes': ('collapse',)
}),
)
# 可折叠的预设字段
prepopulated_fields = {'slug': ('title',)}
# 只读字段
readonly_fields = ['created_at', 'updated_at']
# 过滤器中的外键搜索
autocomplete_fields = ['author', 'category']
def preview_link(self, obj):
if obj.is_published:
return format_html(
'<a href="{}" target="_blank">预览</a>',
obj.get_absolute_url()
)
return "未发布"
preview_link.short_description = "预览"
# 自定义查询集
def get_queryset(self, request):
qs = super().get_queryset(request)
if request.user.is_superuser:
return qs
# 普通用户只能看到自己创建的文章
return qs.filter(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)字段显示配置
配置字段在管理后台中的显示方式:
python
# admin.py
from django.contrib import admin
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from .models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = [
'title', 'author', 'category', 'is_published',
'created_at', 'word_count', 'status_badge'
]
# 自定义字段显示
def word_count(self, obj):
return len(obj.content.split())
word_count.short_description = '字数'
word_count.admin_order_field = 'content' # 可排序
# 显示状态徽章
def status_badge(self, obj):
if obj.is_published:
return format_html(
'<span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px;">已发布</span>'
)
else:
return format_html(
'<span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px;">草稿</span>'
)
status_badge.short_description = '状态'
# 显示富文本内容预览
def content_preview(self, obj):
# 截取前200个字符
preview = obj.content[:200]
if len(obj.content) > 200:
preview += '...'
return mark_safe(preview)
content_preview.short_description = '内容预览'
# 条件字段显示
def get_list_display(self, request):
# 超级用户可以看到所有字段
if request.user.is_superuser:
return self.list_display + ['content_preview']
# 普通用户看不到某些字段
return [field for field in self.list_display if field != 'author']通过这些配置,你可以创建一个功能强大且用户友好的Django管理后台。
小结
Django管理后台基础功能包括:
- ✅ 通过命令行或编程方式创建超级用户
- ✅ 在admin.py中注册模型使其在后台可见
- ✅ 自定义Admin界面提升用户体验
- ✅ 配置字段显示方式和列表过滤器
- ✅ 使用装饰器和ModelAdmin类进行高级定制
掌握Admin基础能够快速构建内容管理系统。
下一篇
我们将学习高级Admin配置技巧。