Django后台管理系统会从模型中读取元数据。对网站数据和文件进行快速操作和管理的系统,使网页内容能够及时更新和调整。
一、创建超级用户
创建指令:python ./manage.py createsuperuser
默认情况下需要先创建用户与密码才能访问后台管理系统,且创建成功的前提是用户的is_staff=True.
二、ModelAdmin类
ModelAdmin类中提供了一些方法与属性用于管理界面中模型的表示。(一般写在admin.py文件中)
1、模型注册两种方法
若想在admin后台呈现自定义模型,需要将模型注册到后台管理系统(若模型名为Message)。
方法一(register装饰器):他接受一个或多个模型类
方法二:
2、ModelAdmin选项
在自定义界面时需要先自定义一个类,该类继承admin.ModelAdmin。
(1)ModelAdmin.actions
在变更列表页上提供的动作列表。
(2)ModelAdmin.actions_on_top(或ModelAdmin.actions_on_bottom)
控制动作栏在页面的那个位置出现。(True or False)
(3)ModelAdmin.actions_selection_counter
控制是否在动作下拉菜单旁显示选择计数器。

(4)ModelAdmin.date_hierarchy
将date_hierarchy设置为模型中DateField或DateTimeField的名称,变化列表页将包含一个基于日期的向下扩展。


也可以使用_ _查找来指定相关模型上的字段
date_hierarchy="table1__time"
注意:date_hierarchy内部使用QuerySet.datetimes()
(5)ModelAdmin.empty_value_display
该属性覆盖记录字段为空的默认显示值

(6)ModelAdmin.exclude
该字段表示从表单排除的字段名列表。
(7)ModelAdmin.fields
使用fields选项在添加和修改页面的表单中进行简单的布局修改。(fields字段的字段名会被显示出来)
(8)ModelAdmin.fieldsets
设置fieldsets控制管理员添加和更改页面的布局。fieldsets包含多个二元组的列表,这些二元组列表的格式是(name,field_options)

如果fieldsets或fields选项都不存在,django将显示非AutoField且有editable=True的字段,顺序与模型中定义的字段相同。
注意:classes是一个包含额外css类的列表或元组,其中定义了两个类collapse和wide
- wide将在管理界面中获得额外的水平空间
- collapse具有名称和collapse样式的fieldsets将初始折叠,使用一个可展示的小部件来切换其可见性。
(9)ModelAdmin.filter_horizontal
由于优化多对多字段选择界面的属性,将默认的多选框增强为双列多选界面。(水平界面)。
(10)ModelAdmin.filter_vertical
和上述功能相同,但是为垂直界面。
(11)ModelAdmin.form
用于自定义表单的属性,允许你完全控制admin页面中使用的表单类,实现自定义验证,字段定制,布局调整等功能。

用户表单与网站管理员表单的作用:
- form.py中的表单模型一般是前台用户提交数据流。

- admin模型中绑定表单模型是用于后台管理员处理数据。


注意:当表单专门用于Admin后台时,不需要在Meta类中指定model和fields。
情况一:在表单模型中定义了model那么也必须要有fields;
情况二:如果在admin模型中定义了fields那么表单模型中的fields会被完全忽略;
综上所述:如果专门写给admin的表单,在forms.py中就不要写Meta类,只写验证方法即可。
(12)ModelAdmin.forfield_overrides
fordield_overrides是将字段类映射成一个参数的字典(就是为某一类型的字段添加一个自定义部件)。

(13)ModelAdmin.inlines
(14)ModelAdmin.list_display
用于控制那些字段显示在管理的变更列表页面。
list_display可以放四种类型的内容:
- 模型字段
- 模型方法(在models.py中定义的方法)
- admin类方法
- 关联字段(foreignkey,manytomany)
(15)ModelAdmin.list_display_links
该字段是控制list_display中的某些字段是否已经被链接到对象的更改页面。(默认情况下更改列表页将第一列也就是list_display指定的第一个字段连接到更改页面,list_display_links是用来改变的)。其值可以为None(完全没有链接);其他需要连接的字段。
(16)ModelAdmin.list_editable
在该属性中列出的字段将作为表单部件显示在变更列表页上,允许用户一次编辑和保存多行。(但一个字段不能同时是list_display_links和list_editable).
(17)ModelAdmin.list_filter
该字段在管理员的更改列表页面右侧栏上激活过滤器。
1、基础用法
2、list_filter支持的数据类型
3、常用过滤器类型
(18)ModelAdmin.list_max_show_all
用于控制全部显示的管理员更改列表页面上可以出现多少个项目。
(19)ModelAdmin.list_per_page
每个分页上会出现多少个项目
(20)ModelAdmin.list_select_related
告诉django在检索管理变更对象列表时使用select_related()可以省去一堆数据库查询。(值为none,列表,元组,布尔值)
- 值为true:select_related()被调用,值为false时将查询list_display如果有外键则调用select_related()
- 值为元组或列表:非空元组或列表会调用select_related().
(21)ModelAdmin.ordering
指定对象列表在django视图中的排序方式。
(22)ModelAdmin.paginator
用于分页的分页器。如果自定义分页器,那么还需要为ModelAdmin.get_paginator()提供一个实现。
(23)ModelAdmin.prepopulated_fields
将该字段设置为一个字典,将字段名映射到预先填充的字段。(用于根据一个或多个字段的值,自动生成另一个字段的值)----前端实时自动填充

在 Admin 编辑页,当你输入标题时,slug 字段会自动同步生成,且是实时、无刷新的。
纯前端JavaScript功能不做后端处理,且只影响admin不影响models.py
prepopulated_fields 不接受 DateTimeField、ForeignKey、OneToOneField 和 ManyToManyField 字段。
(24)ModelAdmin.preserve_filters
在创建,编辑删除对象后,应用的过滤器会被保存到列表视图,该属性可删除过滤器缓存。
(25)ModelAdmin.show_facets
控制是否在管理列表中显示筛选器的facet计数,默认为ShowFacets.ALLOW(当提供_facets查询字符串参数时显示facet计数),ALWAYS(表示始终显示计数),NEVER(从不显示)

(26)ModelAdmin.radio_fields
对于外键或者设置了choices的字段如果存在于radio_fields中将会使用单选按钮接口代替。(假设group是一个外键):

(27)ModelAdmin.autocomplete_fields
用于优化外键和多对多字段的选择,当关联数据量非常大,默认下拉框会变得及其卡顿,而该属性将其升级为带搜索功能的异步加载选择框。(其依赖于search_fields生成搜索查询)
(28)ModelAdmin.raw_id_fields
当数据量极大时,提供一种轻量级的直接输入id的文本输入框(依旧是外键或者多对多的字段)。
(29)ModelAdmin.readonly_fields
模型的只读字段,与list_display一样不仅可以显示模型字段的数据还可以显示模型方法或modeladmin类中方法的输出。
(30)ModelAdmin.save_as
表示使用另存为新的弄能(默认情况对象保存有三种:保存,保存并继续编辑,保存并添加另一个),如果save_as为True则保存并添加另一个将被另存为新取代,该按钮将创建一个新的对象而不是更新现有的对象。
(31)ModelAdmin.save_as_continue
如果为True保存对象后默认重定向到该对象的变更视图,如果为false则重定向到变更列表视图。
(32)ModelAdmin.save_on_top
表示在表格的顶部和底部都添加保存按钮。
(33)ModelAdmin.search_fields
在管理更改列表页面上启用搜索框。


搜索修饰符:

如果你需要额外的或替代的搜索功能能可以使用ModelAdmin.get_search_results()。

(34)ModelAdmin.search_help_text
为搜索框设置一个描述性文本(显示在他的下方)。
(35)ModelAdmin.show_full_result_count
表示是否在过滤后显示全部的对象数量(bool)。
(36)ModelAdmin.sortable_by
如果想要禁止某些列进行排序,可将sortable_by设置为想排序的list_display子集的一个集合(空集合表示禁止所有)。
(37)ModelAdmin.view_on_site
控制是否显示在站点上查看链接。(该值可以是布尔型也可以是一个调用对象)。
- 如果值为true:对象的get_absolute_url()方法将被用来生成网址;
- 如果模型中有get_absolute_url()但不想让"在站点上查看"按钮出现,只需将该值设为false;
- 如果它是一个可调用对象,他接受模型实例作为参数。

3、自定义模板选项

4、ModelAdmin方法
(1)ModelAdmin.save_model(request,obj,form,change)
django中自带该方法,可以通过重写覆盖原来的save_model

(2)ModelAdmin.delete_model(request,obj)
与save_model相似。
(3)ModelAdmin.delete_queryset(request,queryset)
用于删除所选对象queryset
(4)ModelAdmin.save_formset(request,form,formset,change)
用于在保存主模型实例后,保存与之关联的内联表单集(当使用TabularInline or StackedInline在后台管理相关对象时,django会在保存主表单后自动调用此方法来处理内联表单集中的数据)。(formset表示同一页面上多个相同类型的表单集合)
两种内联类:
TabularInline:以表格的形式展示,每一行代表一个关联对象,字段排成一行,适合字段少。
StackedInline:以堆叠的形式展示,每个关联对象有自己的字段块,看起来像独立的表单。
内联的建立:
定义了一个内联类,指定关联模型为Comment;
在AriticleAdmin中用inlines列表包含内联类
extra=1:表示除了已有的评论外,额外显示一个空表单用于添加新评论
savs_formset的重写过程:先调用formset.save父类默认保存,其返保存的实例列表;

(5)ModelAdmin.get_drgering(self,request)
用于动态决定django.admin列表页(list_display)的默认排序规则

(6)ModelAdmin.get_search_results(request,queryset,search_term)
用于自定义或修改列表页搜索时的查询集(queryset:当前初始查询集,search_term:用户在搜索框中输入的搜索词字符串)
如果没有设置search_fields直接返回原查询集(use_distinct=False)
设置了search_fields,django会自动调用get_search_results方法,但如果有额外的过滤条件,还可以重写该方法

(7)ModelAdmin.save_related(request,form,formset,change)
用于在保存主模型实例及所有关联的内联表单集之后,执行额外的相关对象保存操作(change:bool表示修改已有对象【true】还是添加新对象【false】)
注:在保存表单对象时的使用顺序是:
save_model:先保存主模型实例(主表单数据)
save_formset:依次保存每个内联表单集
save_related:最后使用该函数,此时主模型和所有模型关联对象均以保存到数据库中
上述代码:先保存主模型表单中可能存在的多对多关系;其次遍历所有内联表单集,并保存。
何时用:
触发信号或通知:所有相关数据都已保存,可以发送邮件通知、触发 Webhook、更新缓存等。
数据一致性检查:检查主对象和关联对象之间的某些约束(例如总金额、数量限制),如果不符合要求可以抛出异常回滚事务。
生成派生数据:基于所有已保存的数据生成一些汇总信息(例如重新计算订单总价、更新文章的评论数等)。
记录日志:完整记录这次保存操作涉及的所有对象变化。
调用外部 API:将完整的数据集发送给第三方系统。
例如:发送通知邮件:
(8)ModelAdmin.get_autocomplete_fields(request)
用于动态指定哪些外键或多对多字段应该使用自动补全(自动补全功能通过Ajax异步搜索,用户输入时返回匹配的结果)
get_autocomplete_fields方法和autocomplete_fields属性区别:
前者动态后者静态,前者会覆盖后者的设置
使用get_autocomplete_fields条件:
被关联模型必须定义search_fields
(9)ModelAdmin.get_readonly_fields(reqeust,obj=None)
动态指定在编辑页的只读字段

(10)ModelAdmin.get_prepopulated_fields(request,obj=None)
动态指定哪些字段应该根据其他字段的值自动填充。
使用场景
自动生成 slug:根据文章标题生成 URL 友好的 slug 字段。
自动生成文件名:根据标题生成文件名前缀。
根据多个字段组合生成 :例如根据
first_name和last_name生成username。动态决定是否启用:根据用户权限或对象状态决定是否启用预填充。

(11)ModelAdmin.get_list_display(request)
动态决定列表页中显示哪些字段或自定义列

(12)ModelAdmin.get_list_display_links(request,list_display)
动态指定在列表页中哪些字段应该作为链接。点击后进入对象的编辑页面

(13)ModelAdmin.get_exclude(request,obj=None)
动态排除字段,优先级低于get_fields

(14)ModelAdmin.get_fields(request,obj=None)
(15)ModelAdmin.get_fieldsets(request,obj=None)
(16)ModelAdmin.get_list_filter(request)
动态指定列表页右侧过滤器
(17)ModelAdmin.get_list_select_related(request)
动态指定在列表页查询时应该使用select_related()预加载那些外键关系(select_related可以通过sql join在一次查询中把关联对象一起查出来)
返回值:

(18)ModelAdmin.get_search_fields(request)
用于动态指定列表页搜索框应该搜索哪些字段

(19)ModelAdmin.get_sortable_by(request)
动态指定列表页中哪些字段可以被用户点击排序
注意:
字段必须存在于
list_display:你指定的可排序字段必须是list_display中实际显示的字段。方法字段的排序支持 :对于
list_display中的方法,只有当方法设置了admin_order_field属性时才能排序。返回
None的含义 :返回None表示使用默认规则,而不是禁用所有排序。性能考虑:某些字段(如大文本、关联字段)排序可能很慢,可以动态禁用。
与
list_display_links的关系:即使字段是链接,也不一定可排序;两者独立控制。
(20)ModelAdmin.get_inline_instances(request,obj=None)
动态创建和返回内联表单集的实例,返回一个列表,包含 InlineModelAdmin 的实例(例如 TabularInline 或 StackedInline 的实例)

(21)ModelAdmin.get_inlines(request,obj=None)
动态返回应该使用的内联类列表。与get_inline_instances不同的是它返回值为内联类(一个列表)而不是实例。

(22)ModelAdmin.get_urls
允许为管理后台添加自定义的视图和url路由。

对于特定模型的admin功能扩展时get_urls()更适合,以下是urls.py和get_urls()的对比:

注意:get_urls重写时经常用admin_view进行包装。
admin_view的介绍
admin_view是adminsite类的一个方法,用于包装自定义的admin视图,提供一系列自动化功能。
admin_view核心功能
- 权限检查
自动添加admin上下文
缓存控制
- 错误处理
(23)ModelAdmin.get_form(request,obj=None,**kwargs)
控制模型在admin后台使用的表单。(返回用于创建/编辑模型实例的表单类,允许在不同条件动态选择或自定义表单)。
参数说明:
obj:当前正在编辑的对象(如果添加页面,obj为None)
kwargs:其他关键字参数(如fields,exclude,form等)
主要用途:
根据用户角色返回不同的表单
注意:不要每次都修改self.fields,会影响到后续的请求,应该在返回的表单上修改:
根据对象状态返回不同表单
(24)ModelAdmin.get_formsets_with_inlines(request,obj=None)
管理内联表单的重要方法(返回一个生成器,用于遍历模型的所有内联表单集)。

主要用途:
根据权限控制内联显示
根据对象状态控制内联
(25)ModelAdmin.formfield_for_foreignkey(db_field,request,**kwargs)
控制外键字段显示和行为的方法。(可以限制可选的外键的对象范围)

主要用途:
根据当前用户过滤外键选项
根据对象状态过滤
(26)ModelAdmin.formfield_for_manytomany(request,db_field,**kwargs)
允许自定义模型中多对多字段在admin表单中的显示方式,特别是限制可选对象范围和控制界面表现。
参数:
db_field:多对多字段对象
request:当前HTTP请求
kwargs:其他参数(例:queryset)
主要用途:
根据当前用户过滤选项

控制选择界面

(27)ModelAdmin.formfield_for_choice_field(request,db_field,**kwargs)
用于控制带choices选项的字段(例:CharField/IntegerField设置了choices属性),它用于动态修改选项列表或控制选项的行为。
参数:
db_field:choices字段对象
request:当前HTTP请求
kwargs:其他参数(例:choices)
主要用途:
动态修改选项列表(根据角色显示不同的choices)


根据对象状态过滤选项

注:resolver_match是url解析器匹配当前请求后返回的对象(它包含了当前url的所有解析信息)
1、resolver_match核心属性
- resolver.func:视图函数
- resolver.url_name:url名称
- resolver.view_name:视图名称
- resolver.app_name:应用名称
- resolver.namespace:命名空间
- resolver.route:url路由
- resolver.args:位置参数
- resolver.kwargs:关键字参数
- resolver.captured_kwargs:捕获的参数
- resolver.app_names:应用名称列表
- resolver.namespaces:命名空间列表
(28)ModelAdmin.get_changelist(request,**kwargs)
用于显示模型列表页的ChangeList类(默认的ChangeList类包含功能:列表显示字段,排序,过滤,搜索,分页)
python
from django.contrib.admin.views.main import ChangeList
class CustomChangeList(ChangeList):
"""
自定义 ChangeList,添加额外功能
"""
def get_queryset(self, request):
# 获取原始查询集
qs = super().get_queryset(request)
# 添加自定义过滤
qs = qs.filter(is_active=True)
# 添加额外的注解
from django.db.models import Count
qs = qs.annotate(
related_count=Count('related_model')
)
return qs
def get_ordering(self, request, queryset):
"""
自定义默认排序
"""
ordering = super().get_ordering(request, queryset)
if not ordering:
# 默认按创建时间倒序
ordering = ['-created_at']
return ordering
class ArticleAdmin(admin.ModelAdmin):
def get_changelist(self, request, **kwargs):
return CustomChangeList
(29)ModelAdmin.get_changelist_form(request,**kwargs)
用于在列表页(changelist)进行行内编辑的表单类
与list_editable的关系

(30)ModelAdmin.get_changelist_formset(request,**kwargs)
用于在列表页进行批量编辑(返回一个表单集)
与list_editable关系

自定义批量编辑表单集
python
from django import forms
from django.forms import BaseModelFormSet
from django.contrib.admin import helpers
class ArticleFormSet(BaseModelFormSet):
"""
自定义表单集,用于批量编辑文章
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 为每个表单添加自定义CSS类
for form in self.forms:
for field in form.fields.values():
field.widget.attrs['class'] = 'vTextField'
def clean(self):
"""
全局验证所有表单
"""
super().clean()
# 检查是否有重复的标题(示例)
titles = []
for form in self.forms:
if form.cleaned_data and not form.cleaned_data.get('DELETE', False):
title = form.cleaned_data.get('title')
if title in titles:
raise forms.ValidationError(f"标题 '{title}' 重复!")
titles.append(title)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'status', 'category', 'author']
list_editable = ['status', 'category']
def get_changelist_formset(self, request, **kwargs):
kwargs['formset'] = ArticleFormSet
return super().get_changelist_formset(request, **kwargs)
(31)ModelAdmin.lookup_allowed(lookup,value)
用于安全控制查询过滤的重要方法(其判断是否允许在admin列表页使用特定的查询参数进行过滤);目的:防止用户通过URL参数进行未授权的查询。
参数:
lookup:特定的查询参数名(如:status__exact/author__id__exact)
value:查询参数值
lookup_allowed默认行为

自定义查询参数与限制某些字段的查询:


(32)ModelAdmin.has_view_permission(request,obj=None)
用于控制用户是否有权限查看模型对象(返回值为布尔值)
基础权限控制:

基于对象状态

(33)ModelAdmin.has_add_permission(request)
是否有添加权限
python
class ArticleAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
"""
控制用户是否能添加新文章
只在添加页面调用,没有 obj 参数
"""
# 超级用户可以添加
if request.user.is_superuser:
return True
# 检查是否有添加权限
if request.user.has_perm('myapp.add_article'):
return True
# 只有特定角色的用户可以添加
if request.user.groups.filter(name='Editors').exists():
return True
return False
# 添加页面的额外控制
def add_view(self, request, form_url='', extra_context=None):
if not self.has_add_permission(request):
raise PermissionDenied("您没有添加权限")
return super().add_view(request, form_url, extra_context)
(34)ModelAdmin.has_change_permission(request,obj=None)
修改权限
python
class OrderAdmin(admin.ModelAdmin):
def has_change_permission(self, request, obj=None):
"""
控制用户是否能修改订单
obj: 要修改的具体订单对象
"""
# 基础检查
if not request.user.is_authenticated:
return False
# 超级用户可以修改所有
if request.user.is_superuser:
return True
# 如果要修改具体对象
if obj:
# 已发货的订单不能修改
if obj.status == 'shipped':
return False
# 只能修改自己的订单
if obj.customer.user == request.user:
return True
# 管理员可以修改所有
if request.user.has_perm('orders.change_order'):
return True
return False
# 列表页批量修改权限
return request.user.has_perm('orders.change_order')
(35)ModelAdmin.has_delete_permission(request,obj=None)
删除权限
python
class DocumentAdmin(admin.ModelAdmin):
def has_delete_permission(self, request, obj=None):
"""
控制用户是否能删除文档
obj: 要删除的具体文档对象
"""
# 基础权限
if not request.user.is_authenticated:
return False
# 只有管理员可以删除
if not request.user.is_superuser:
return False
# 如果要删除具体对象
if obj:
# 重要文档不能删除
if obj.is_important:
return False
# 有关联对象的不能删除
if obj.related_objects.exists():
return False
return True
# 删除前的额外检查
def delete_view(self, request, object_id, extra_context=None):
obj = self.get_object(request, object_id)
# 自定义删除前检查
if obj and obj.protected:
self.message_user(request, "该文档受保护,不能删除", level='ERROR')
return redirect('..')
return super().delete_view(request, object_id, extra_context)
# 批量删除的处理
def get_actions(self, request):
actions = super().get_actions(request)
if 'delete_selected' in actions:
if not self.has_delete_permission(request):
del actions['delete_selected']
return actions
(36)ModelAdmin.has_module_permission(request)
模块权限
python
class DashboardAdmin(admin.ModelAdmin):
def has_module_permission(self, request):
"""
控制用户是否能在admin首页看到这个模块
返回False时,整个模型都不会在admin界面显示
"""
# 超级用户总是能看到
if request.user.is_superuser:
return True
# 检查是否有任何模型权限
has_any_perm = any([
self.has_view_permission(request),
self.has_add_permission(request),
self.has_change_permission(request),
self.has_delete_permission(request),
])
if not has_any_perm:
return False
# 特定用户组才能看到
allowed_groups = ['Managers', 'Editors']
if request.user.groups.filter(name__in=allowed_groups).exists():
return True
return False
(37)ModelAdmin.get_queryset(request)
控制列表页显示哪些数据(返回用于在admin列表页面显示的查询集)
基于用户过滤:

多租户数据隔离:

软过滤删除:

(38)ModelAdmin.message_user(reqeust,str)
向用户显示消息(例:在admin界面中间向用户显示一条成功/错误/警告等的消息,这些消息会显示在页面顶部)

消息级别:

(39)ModelAdmin.get_paginator(request,queryset,per_page,orphans=0,allow_empty_first_page=True)
用于控制列表表页分页(返回一个分页器对象,用于在admin列表页对查询结果进行分页显示)
参数:
queryset:要分页的查询集
per_page:每页显示的数量
orphans:最后一页最少显示数量
allow_empty_first_page:是否允许空的第一页
默认分页控制:

自定义每页显示数量

(40)ModelAdmin.response_add(request,obj,post_url_continue=None)
用于处理添加操作后的响应,它决定了当用户成功添加一个新对象后,应该重定向到那个页面以及显示什么消息。(response_add方法在add_view成功保存对象后被调用,用于返回HTTP响应)
参数:
post_url_continue:继续编辑的url
默认行为

自定义重定向:

(41)ModelAdmin.response_change(request,obj)
用于处理操作后的响应,它决定了当用户成功修改一个现有对象后,应该重定向到那个页面以及显示什么消息。(response_change方法在change_view成功保存对象后被调用,用于返回HTTP响应)。
默认行为:

自定义重定向:
根据对象状态重定向

(42)ModelAdmin.response_delete(request,obj_display,obj_id)
用于处理删除操作后的响应,决定了用户成功删除一个对象后,应该重定向到哪个页面以及显示什么消息。(response_delete在delete_view成功删除对象后调用,用于返回HTTP响应)
参数:
obj_display:被删除对象的字符串表示
obj_id:被删除对象的id
默认行为:

自定义重定向

根据条件重定向
python
class OrderAdmin(admin.ModelAdmin):
def response_delete(self, request, obj_display, obj_id):
# 记录删除日志
self.log_deletion(request, obj_display, obj_id)
# 根据来源重定向
referer = request.META.get('HTTP_REFERER', '')
if 'trash' in referer:
# 从回收站删除,返回回收站
redirect_url = reverse('admin:app_order_changelist') + '?status=deleted'
elif 'search' in referer:
# 从搜索结果删除,返回搜索结果页
redirect_url = referer
else:
# 默认返回列表页
redirect_url = reverse('admin:app_order_changelist')
self.message_user(
request,
f'订单 #{obj_display} 已删除。',
level='WARNING'
)
return HttpResponseRedirect(redirect_url)
(43)ModelAdmin.get_formset_kwargs(request,obj,inline,prefix)
用于自定义内联表单初始化参数,返回用于初始化内联表单集的关键字参数(允许在创建内联表单集时传递额外的参数)
参数:
inline:内联管理实例
prefix:表单集的前缀
传递额外参数给表单集:

动态设置表单集属性:

(44)ModelAdmin.get_changeform_initial_data(reqeust)
设置表单初始值(返回一个字典,用于在添加或编辑表单中设置字段的初始值)
设置固定初始值:

基于用户的初始值:

(45)ModelAdmin.get_deleted_objects(request,obj)
用于获取删除操作相关对象(返回一个元组,包含将被删除的对象列表,对象数量,以及每个对象的详细信息)。
其返回值的含义:

自定义删除确认页面:

显示详细删除信息:



























