Django Admin 指南
使用 ModelAdmin 选项、内联模型、自定义动作和高级配置定制 Django admin 界面。
1. 基本 ModelAdmin
from django.contrib import admin
from django.utils.html import format_html
from .models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ("title", "author", "status", "view_count", "created_at")
list_editable = ("status",)
list_per_page = 25
list_filter = ("status", "category", "created_at")
search_fields = ("title", "content", "author__name")
date_hierarchy = "created_at"
readonly_fields = ("slug", "view_count", "created_at")
prepopulated_fields = {"slug": ("title",)}
fieldsets = (
(None, {"fields": ("title", "slug", "author", "category")}),
("内容", {"fields": ("content", "cover_image")}),
("发布", {"fields": ("status", "published_at"), "classes": ("collapse",)}),
)
2. 自定义 Admin 动作
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
actions = ["publish_selected", "export_csv"]
@admin.action(description="发布选中文章")
def publish_selected(self, request, queryset):
updated = queryset.filter(status="draft").update(status="published")
self.message_user(request, f"已发布 {updated} 篇文章。")
@admin.action(description="导出为 CSV")
def export_csv(self, request, queryset):
import csv
from django.http import HttpResponse
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = 'attachment; filename="articles.csv"'
writer = csv.writer(response)
writer.writerow(["ID", "标题", "作者", "状态"])
for obj in queryset:
writer.writerow([obj.pk, obj.title, obj.author.name, obj.status])
return response
3. 内联模型
class OrderItemInline(admin.TabularInline):
model = OrderItem
extra = 1
fields = ("product", "quantity", "unit_price")
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
inlines = [OrderItemInline]
list_display = ("order_number", "customer", "total", "status")
4. 覆盖管理视图
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super().get_urls()
custom = [
path("analytics/", self.admin_site.admin_view(self.analytics_view)),
]
return custom + urls
# 仅显示当前用户的文章
def get_queryset(self, request):
qs = super().get_queryset(request)
if not request.user.is_superuser:
return qs.filter(author=request.user)
return qs