掌握Django内联TabularInline和StackedInline示例

2025-04-08T08:45:44+08:00 | 3分钟阅读 | 更新于 2025-04-08T08:45:44+08:00

Macro Zhao

掌握Django内联TabularInline和StackedInline示例

推荐超级课程:

@TOC

Django 的管理界面是一个强大的工具,用于管理应用程序的数据。它最有用的功能之一是能够使用内联模型管理类在同一页面上编辑相关模型的数据。在本教程中,我们将通过详细的示例介绍如何使用 TabularInlineStackedInline

前提条件

  • Python 3.8 或更高版本
  • Django 4.0 或更高版本

Django 内联管理简介

Django 内联管理类 (TabularInlineStackedInline) 允许我们在同一页面上添加相关模型数据。这对于具有外键关系的模型特别有用。

设置 Django 项目

首先,确保您已安装 Django。创建一个新的 Django 项目和应用程序:

django-admin startproject myproject  
cd myproject  
django-admin startapp myapp

settings.py 中将 myapp 添加到 INSTALLED_APPS

# settings.py  
  
INSTALLED_APPS = [  
    # ...  
    'myapp',  
]

创建模型

创建两个模型,AuthorBook,其中每本书都有一个指向作者的外键。

# myapp/models.py  
  
from django.db import models  
  
class Author(models.Model):  
    name = models.CharField(max_length=100)  
  
    def __str__(self):  
        return self.name  
  
  
class Book(models.Model):  
    author = models.ForeignKey(Author, on_delete=models.CASCADE)  
    title = models.CharField(max_length=200)  
    publication_date = models.DateField()  
  
    def __str__(self):  
        return self.title

运行迁移以创建数据库表:

python manage.py makemigrations  
python manage.py migrate

在管理中注册模型

接下来,在 Django 管理站点中注册模型:

# myapp/admin.py  
  
from django.contrib import admin  
from .models import Author, Book  
  
  
admin.site.register(Author)  
admin.site.register(Book)

使用 TabularInline

要使用 TabularInline,请创建一个内联类并将其与父模型关联:

# myapp/admin.py  
  
from django.contrib import admin  
from .models import Author, Book  
  
  
class BookInline(admin.TabularInline):  
    model = Book  
    extra = 2  # 显示的额外表单数量  
  
  
class AuthorAdmin(admin.ModelAdmin):  
    inlines = [BookInline]  
  
  
admin.site.register(Author, AuthorAdmin)  
admin.site.register(Book)

使用此设置,您可以直接在作者的 admin 页面上添加和编辑书籍。

使用 StackedInline

要使用 StackedInline,只需将 TabularInline 替换为 StackedInline

# myapp/admin.py  
  
from django.contrib import admin  
from .models import Author, Book  
  
class BookInline(admin.StackedInline):  
    model = Book  
    extra = 2  # 显示的额外表单数量  
  
  
class AuthorAdmin(admin.ModelAdmin):  
    inlines = [BookInline]

StackedInline 提供了比 TabularInline 更详细的布局。

自定义内联管理

您可以通过指定字段、设置只读字段或添加自定义方法来进一步自定义内联管理表单:

# myapp/admin.py  
  
from django.contrib import admin  
from .models import Author, Book  
  
  
class BookInline(admin.TabularInline):  
    model = Book  
    extra = 2 # 显示的额外表单数量  
    fields = ['title', 'publication_date']  # 指定显示的字段  
    readonly_fields = ['publication_date']  # 使某些字段变为只读  
  
    def some_custom_method(self, obj):  
        # 自定义方法以显示额外信息  
        return obj.title  
  
class AuthorAdmin(admin.ModelAdmin):  
    inlines = [BookInline]

使用 CSS 和 JavaScript 增强内联管理

您可能希望包含自定义 CSS 或 JavaScript 以增强内联管理界面:

# myapp/admin.py  
class BookInline(admin.TabularInline):  
    model = Book  
    extra = 1  
  
    class Media:  
        css = {  
            'all': ('css/custom_admin.css',)  # 包含自定义 CSS  
        }  
        js = ('js/custom_admin.js',)  # 包含自定义 JavaScript  

将您的自定义 CSS 和 JavaScript 文件放置在相应的静态目录中。

添加自定义 CSS 和 JavaScript

要添加自定义 CSS 和 JavaScript,您需要覆盖默认的管理模板。 创建用于静态文件的目录,例如 css 和 js:

mkdir staticfilescss   
mkdir staticfilesjs  
mkdir static

添加您的自定义 CSS 和 JavaScript。

staticfiles/css/custom_admin.css:

/* 示例:更改内联表单的背景颜色 */  
.inline-related {  
    background-color: #f9f9f9;  
    border: 1px solid #ddd;  
    padding: 10px;  
    margin-bottom: 10px;  
    border-radius: 5px;  
}

staticfiles/js/custom_admin.js:

document.addEventListener('DOMContentLoaded', function() {  
    // 示例:为内联表单中的按钮添加事件监听器  
    document.querySelectorAll('.inline-related').forEach(function(inline) {  
        var deleteButton = inline.querySelector('.delete');  
        if (deleteButton) {  
            deleteButton.addEventListener('click', function() {  
                alert('您将要删除一本书!');  
            });  
        }
    });  
});

更新 Settings 和 urls.py 文件

确保 Django 知道在哪里查找您的静态文件和模板。 myproject/settings.py:

# myproject/settings.py  
  
# 模板  
TEMPLATES = [  
    {  
        'BACKEND': 'django.template.backends.django.DjangoTemplates',  
        'DIRS': [BASE_DIR / 'templates'],  
        'APP_DIRS': True,  
        'OPTIONS': {  
            'context_processors': [  
                'django.template.context_processors.debug',  
                'django.template.context_processors.request',  
                'django.contrib.auth.context_processors.auth',  
                'django.contrib.messages.context_processors.messages',  
            ],  
        },  
    },  
]  
  
  
# 静态文件 (CSS, JavaScript, Images)  
STATIC_URL = '/static/'  
STATIC_ROOT = BASE_DIR / 'static'  
  
STATICFILES_DIRS = [  
    BASE_DIR / 'staticfiles',  
]

myproject/urls.py:

# myproject/urls.py  
  
from django.contrib import admin  
from django.urls import path  
from django.conf import settings  
from django.conf.urls.static import static  
  
  
urlpatterns = [  
    path('admin/', admin.site.urls),  
]  
  
if settings.DEBUG:  
    urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)

运行

django collectstatic 命令并运行服务器:

python manage.py collectstatic  
  
python manage.py runserver

结论

使用 Django 的 TabularInlineStackedInline 类,您可以创建一个更高效、用户友好的管理界面来管理相关模型。根据您的项目需求自定义内联表单,并根据需要使用额外的 CSS 和 JavaScript 增强管理体验。

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee