使用Django意味着后台框架的幾乎所有內容都會和Django產生互動,排除功能全部手擼的情況.
Django 后台admin有大量的屬性和方法,擁有強大的功能和自定義能力.通過完整的代碼來看Django admin的基礎設置和高級用法,並結合form表單來實現深度自定義.
簡單使用
如果只是使用admin自帶的數據管理功能,只需要將模型注冊到admin中,就可以實現.
1
2
3
4
5
|
from django.contrib import admin
admin.site.register(News)
admin.site.register(NewsType)
admin.site.site_header = "數據庫"
admin.site.index_title = "新聞后台"
|
Django后台會將對應數據表的所有字段進行展示,默認點擊 id 會進入修改頁面,對應 change_form.html 模板.
自定義admin類
使用admin也可以自定義一個admin的類,來自定義后台實現的屬性和方法,然后通過 register() 來將自定義的類和模型注冊在一起.
注冊方式有兩種,一種是使用類裝飾器,一種是使用 site
1
2
3
4
5
6
7
8
9
|
from
django.contrib
import
admin
# 裝飾器注冊
@admin
.register(ModelClass)
class
CustomAdmin(admin.ModelAdmin):
list_display
=
'__all__'
# 使用site
class
CustomAdmin(admin.ModelAdmin):
exclude
=
[
'id'
]
admin.site.register(CustomAdmin, ModelClass)
|
admin顯示屬性的設置
ModelAdmin中的屬性設置
admin可以設置在列表頁和詳情頁顯示的字段以及搜索字段等的限制,在admin的類中可以直接定義.
以使用較多的 ModelAdmin 為例, ModelAdmin 源碼中的屬性有:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# 在列表頁顯示的字段,默認會顯示所有字段,有對應的方法可以重寫
list_display
=
(
'__str__'
,)
# 在列表頁顯示的字段中,可以鏈接到change_form頁面的字段
list_display_links
=
()
# 右側的篩選,必須是字段,可以繼承自SimpleListFilter來自定義篩選字段和規則,SimpleListFilter的方法在后面詳細介紹
list_filter
=
()
# 聯表查詢是否自動查詢,可以是布爾,列表或元組,如果是列表或元組,則級聯查詢指定的字段
list_select_related
=
False
# 列表頁每頁展示的條數
list_per_page
=
100
# 分頁,顯示全部,真是數據小於該值時才會顯示全部
list_max_show_all
=
200
# 在列表頁可以編輯的字段
list_editable
=
()
# 在列表頁可以模糊搜索的字段
search_fields
=
()
# 對Date和DateTime類型進行搜索
date_hierarchy
=
None
# 在change_form頁面,按鈕為,save按鈕的值(save as new和save add another)
save_as
=
False
# 點擊保存並繼續編輯
save_as_continue
=
True
# save按鈕的位置,是True則顯示在頁面上方
save_on_top
=
False
# 自定義分頁類
paginator
=
Paginator
# 詳細頁面,刪除、修改,更新后跳轉回列表后,是否保留原搜索條件管理員現在在創建,編輯或刪除對象后保留列表視圖中的過濾器。
# 可以將此屬性設置為False,以恢復之前清除過濾器的行為。
preserve_filters
=
True
# 在詳情頁面,如果有FK到其他表,在詳情頁中可以動態的填加或刪除級聯數據
inlines
=
[]
admin中action操作的設置
admin中的action是指在列表頁的動作,默認為刪除所選的條目,可以自定義填加動作,將動作注冊到action中,需要是一個方法
# 定制action中的操作
actions
=
[]
action_form
=
helpers.ActionForm
# action選項顯示的位置,頁面上方或者頁面下方
actions_on_top
=
True
actions_on_bottom
=
False
# 是否顯示action選擇的個數
actions_selection_counter
=
True
checks_class
=
ModelAdminChecks
BaseModelAdmin中的屬性
除了ModelAdmin中的屬性,也可以自定義在其父類BaseModelAdmin中的屬性和方法,是一些通用的,在繼承子BaseModelAdmin的類中也可以完成的屬性設置.一般是詳情頁的屬性.
# 自動補全,外鍵查詢數據多時,方便查找
autocomplete_fields
=
()
# 詳情頁,針對外鍵和M2M字段變成input框形式
raw_id_fields
=
()
# 詳情頁面展示的字段
fields
=
None
# 詳情頁面排除的字段,字段可以是數據庫中的也可以是自定義的
exclude
=
None
# 在詳情頁面對數據進行分隔顯示,對應到admin模板中的'fieldsets.html'
fieldsets
=
None
# 為詳情頁指定form表單,可以自定義顯示的數據,字段
form
=
forms.ModelForm
# 下面兩個是M2M顯示時,數據移動選擇.可以參考admin中用戶的權限操作
filter_vertical
=
()
# 縱向展示
filter_horizontal
=
()
# 橫向展示
# 詳情頁面使用radio顯示選項,FK默認使用select
radio_fields
=
{}
# 填加頁面,在某字段輸入值后,自動填加到指定字段
# prepopulated_fields = {"email": ("user",)},email字段會在用戶填加user字段時自動填充
prepopulated_fields
=
{}
# 詳情頁指定顯示的插件,后面詳細說明
formfield_overrides
=
{}
# 詳情頁面的只讀字段
readonly_fields
=
()
# 詳情頁面排序規則
ordering
=
None
# 禁止某些排序,為空則禁止所有的排序
sortable_by
=
None
# 編輯時是否在頁面上顯示view on set,可以通過方法來返回一個鏈接,后面說明
view_on_site
=
True
# 列表頁,模糊搜索后面顯示的數據個數樣式
# 為True是顯示條數,為False時顯示全部
show_full_result_count
=
True
checks_class
=
BaseModelAdminChecks
|
模板的定制
指定自定義模板
在ModelAdmin中自帶了幾個指定模板的屬性,可以自己定義HTML文件,來指定給某個模板頁面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# Custom templates (designed to be over-ridden in subclasses)
# 添加數據模板頁
add_form_template
=
None
# 修改數據的模板頁
change_form_template
=
None
# 修改多條數據的模板頁
change_list_template
=
None
# 刪除確認信息模板頁
delete_confirmation_template
=
None
# 刪除關聯數據的確認頁
delete_selected_confirmation_template
=
None
# 修改歷史的模板頁
object_history_template
=
None
# 彈出框模板頁
popup_response_template
=
None
|
重寫自帶模板
在django admin里面有自己寫好的模板,include模板,每個app也有對應的模板
admin的自帶模板在項目的 django/contrib/admin/templates/admin ,目錄下面
include 文目錄下是 include 語法包含的模板。
change_form.html 是數據修改頁面的模板,如果想在數據詳情頁面自定義顯示的內容,可以自定義這個頁面
模板使用的全都是模板語法,注意模板語法的繼承機制,在當前頁面重寫的元素,不會直接顯示。
fieldset.htlm 是拼接成詳情頁的塊。前面提到,自定義admin類中的 fieldset 屬性,可以自定義詳情頁,使數據字段分塊顯示,就是改變了傳給這個頁面的值。
例如,使用 if 語句來動態添加jQuery和 div 標簽,只有在訪問某個app的數據時添加
1
2
3
4
5
6
7
8
|
{
%
if
app_name
in
request.path
%
}
<div>
<fieldset
class
=
"custom"
>
<div
id
=
"div"
><
/
div>
<
/
fieldset>
{
%
endif
%
}
|
結合form表單
django admin結合form表單,重寫 fieldset.html 來實現數據詳情頁面的深度自定義,通過處理form表單提交的數據,來實現后台功能的完全自定義。
django的admin中可以指定form類,來自定義顯示的內容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from
django
import
forms
# TagValueManager是自定義的類
from
tag_manager
import
TagValueManager
class
CustomAddForm(forms.ModelForm):
""" 根據標簽的id,動態生成下拉選項框 """
for
i
in
TagValueManager.all_tag:
locals
()[
'field_tag_id_{}'
.
format
(
i[
'id'
])]
=
forms.ChoiceField(
choices
=
TagValueManager.get_choice(
i[
'id'
]),
label
=
i[
'name'
])
class
Meta:
model
=
CandidateTag
fields
=
'__all__'
exclude
=
[
'tag_id'
,
'tag_value'
,
'ext_1'
,
'ext_2'
,
'candidate_id'
]
|
注意:在form表單中動態生成的屬性,必須使用 fields='__all__‘ 屬性,否則不會顯示,可以結合 exclude 屬性來控制需要顯示的表單
然后在admin中注冊form類
1
2
3
4
5
6
|
class
CandidateTagAdmin(admin.ModelAdmin):
list_display
=
[
'id'
,
'tag_count'
,
]
form
=
CustomAddForm
|
自定義列表頁來源
除了可以通過修改admin的屬性,來實現列表頁展示字段的自定義,也可以對列表頁數據進行篩選,例如,篩選出活躍的用戶等,這個可以在 action 中定義新的方法
也可以重寫admin中的 get_queryset 方法,返回的qs是重新篩選之后的數據,可以避免一些業務邏輯上的誤操作
這里的代碼展示了,在列表頁,展示其他表中的數據,注冊模型表的數據沒有展示
1
2
3
4
5
6
7
|
def
get_queryset(
self
, request):
"""
從candidate表中查詢數據,在list_display中統計其標簽個數
"""
qs
=
Candidate.objects.
all
().order_by(
'id'
)
return
qs
## 處理form數據
|
給admin類定義form屬性之后,在詳情頁面傳回的數據,會帶上form表單里面的數據,然后結合業務邏輯處理這個數據
例如,業務場景,接受form數據,保存到其他幾張表,對於展示數據的表,不進行任何操作,那就需要重寫 save_model 方法,這個方法調用了模型的 save 方法
重寫這個方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
def
save_model(
self
, request, obj, form, change):
"""
重寫save_model方法
"""
candidate_id
=
request.path.split(
'/'
)[
4
]
post_dict
=
request.POST
# 根據返回的form表單的標簽來確定修改的tag_id
include_field
=
'field_tag_id_'
for
key, value
in
post_dict.items():
if
include_field
in
key:
tag_id
=
key.split(
'_'
)[
-
1
]
tag_value
=
value
try
:
obj, created
=
CandidateTag.objects.update_or_create(
defaults
=
{
'tag_value'
: tag_value}, candidate_id
=
candidate_id, tag_id
=
tag_id)
except
Exception as e:
tag_name
=
TagValueManager.all_tag.get(
id
=
tag_id)[
'name'
]
messages.add_message(request, messages.ERROR,
'求職者的"{}"標簽信息保存失敗'
.
format
(tag_name))
|
擴展
在 get_queryset 方法中,展示類模型中的統計數據,這個統計數據,不是在數據庫中生成的,實在模型類中定義的方法,這個方法的返回值,可以在列表頁中直接展示。例如上文中說道的標簽的個數
同時,也可以返回一個HTML標簽,模板語法中獲取這個字段時,得到的是一個HTML標簽,直接渲染
1
2
3
4
5
6
7
8
9
10
|
from
django.utils.safestring
import
mark_safe
# 使用mark_safe
@mark_safe
def
get_user_dept(
self
,obj):
""" 這個方法在模型中 """
return
"<p>this is a HTML tag</p>"
# 允許HTML標簽
get_report_depts.allow_tags
=
True
# HTML展示時的字段名
get_report_depts.short_description
=
'所屬部門'
|
總結
以上所述是小編給大家介紹的Django admin高級用法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!