Django Admin 配置详解

发布于:2025-07-15 ⋅ 阅读:(20) ⋅ 点赞:(0)

Django 的管理界面是一个强大的工具,可帮助你轻松管理网站内容。下面详细介绍如何配置和定制 Django Admin。

1. 启用 Django Admin

首先确保 django.contrib.admin 已在 settings.py 中启用:

# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 你的应用
]

urls.py 中添加 Admin 路由:

# urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

2. 创建管理员账户

python manage.py createsuperuser

按照提示输入用户名、邮箱和密码。

3. 注册模型到 Admin

在应用的 admin.py 中注册模型:

# myapp/admin.py
from django.contrib import admin
from .models import Author, Book, Category

admin.site.register(Author)
admin.site.register(Book)
admin.site.register(Category)

4. 自定义 Admin 界面

4.1 自定义 ModelAdmin
# myapp/admin.py
from django.contrib import admin
from .models import Author, Book, Category

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'publication_date', 'is_published')
    list_filter = ('author', 'publication_date', 'categories')
    search_fields = ('title', 'author__name')
    ordering = ('-publication_date',)
    date_hierarchy = 'publication_date'
    fieldsets = (
        (None, {
            'fields': ('title', 'author', 'categories')
        }),
        ('Advanced options', {
            'classes': ('collapse',),
            'fields': ('publication_date', 'is_published', 'description'),
        }),
    )
    filter_horizontal = ('categories',)
4.2 自定义列表页
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('name', 'email', 'birth_date', 'age')
    list_per_page = 50
    list_editable = ('email',)
    list_display_links = ('name',)
    
    def age(self, obj):
        import datetime
        if obj.birth_date:
            return datetime.date.today().year - obj.birth_date.year
        return "N/A"
    age.short_description = 'Age'
4.3 自定义编辑页
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name',)}
    readonly_fields = ('created_at', 'updated_at')
    
    def save_model(self, request, obj, form, change):
        if not change:  # 创建时
            obj.created_by = request.user
        obj.updated_by = request.user
        super().save_model(request, obj, form, change)

5. 添加自定义操作

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    actions = ['mark_as_published', 'mark_as_unpublished']
    
    def mark_as_published(self, request, queryset):
        rows_updated = queryset.update(is_published=True)
        self.message_user(request, f'Successfully published {rows_updated} books.')
    mark_as_published.short_description = "Mark selected books as published"
    
    def mark_as_unpublished(self, request, queryset):
        rows_updated = queryset.update(is_published=False)
        self.message_user(request, f'Successfully unpublished {rows_updated} books.')
    mark_as_unpublished.short_description = "Mark selected books as unpublished"

6. 自定义 Admin 站点

# myproject/admin.py
from django.contrib.admin import AdminSite
from django.utils.translation import gettext_lazy as _

class MyAdminSite(AdminSite):
    site_header = _('My Bookstore Admin')
    site_title = _('My Bookstore Admin Portal')
    index_title = _('Welcome to My Bookstore')
    logout_template = 'admin/logout.html'

admin_site = MyAdminSite(name='myadmin')

# 注册模型到自定义站点
from myapp.models import Author, Book
admin_site.register(Author)
admin_site.register(Book)

修改 urls.py 使用自定义站点:

# myproject/urls.py
from django.urls import path
from .admin import admin_site

urlpatterns = [
    path('admin/', admin_site.urls),
]

7. 自定义 Admin 模板

  1. 创建模板目录结构:
myproject/
    templates/
        admin/
            base_site.html
            index.html
            book/
                change_list.html
  1. 自定义基础模板示例:
<!-- templates/admin/base_site.html -->
{% extends "admin/base.html" %}

{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">My Bookstore Admin</a></h1>
{% endblock %}

{% block nav-global %}{% endblock %}

8. 添加自定义视图

# myapp/admin.py
from django.urls import path
from django.shortcuts import render
from django.contrib import admin

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    # ...

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('stats/', self.admin_site.admin_view(self.stats_view), name='book-stats'),
        ]
        return custom_urls + urls
    
    def stats_view(self, request):
        total_books = Book.objects.count()
        published_books = Book.objects.filter(is_published=True).count()
        
        context = {
            **self.admin_site.each_context(request),
            'title': 'Book Statistics',
            'total_books': total_books,
            'published_books': published_books,
        }
        return render(request, 'admin/book_stats.html', context)

9. 多对多字段优化

使用 filter_horizontalfilter_vertical

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    filter_horizontal = ('categories',)
    # 或者使用 filter_vertical
    # filter_vertical = ('categories',)

10. 只读字段和权限控制

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    readonly_fields = ('created_at', 'updated_at')
    
    def has_delete_permission(self, request, obj=None):
        # 只有超级用户可以删除作者
        return request.user.is_superuser
    
    def has_change_permission(self, request, obj=None):
        # 限制普通管理员修改某些字段
        if obj and request.user.has_perm('myapp.change_author'):
            return True
        return False

11. 日期层级导航

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    date_hierarchy = 'publication_date'

12. 自定义过滤器

from django.contrib.admin import SimpleListFilter

class PublishedListFilter(SimpleListFilter):
    title = 'Publication Status'
    parameter_name = 'status'
    
    def lookups(self, request, model_admin):
        return (
            ('published', 'Published'),
            ('unpublished', 'Unpublished'),
        )
    
    def queryset(self, request, queryset):
        if self.value() == 'published':
            return queryset.filter(is_published=True)
        if self.value() == 'unpublished':
            return queryset.filter(is_published=False)

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    list_filter = (PublishedListFilter,)

13. 内联模型

from django.contrib import admin
from .models import Author, Book

class BookInline(admin.TabularInline):
    model = Book
    extra = 1
    fields = ('title', 'publication_date', 'is_published')

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    inlines = [BookInline]

以上配置可以帮助你充分利用 Django Admin 的强大功能,根据实际需求进行灵活定制,提高管理效率。


网站公告

今日签到

点亮在社区的每一天
去签到