Django admin高級用法

@[toc]html

Django admin高級用法

使用Django意味着後臺框架的幾乎全部內容都會和Django產生互動,排除功能所有手擼的狀況.python

Django 後臺admin有大量的屬性和方法,擁有強大的功能和自定義能力.經過完整的代碼來看Django admin的基礎設置和高級用法,並結合form表單來實現深度自定義.jquery

簡單使用

若是隻是使用admin自帶的數據管理功能,只須要將模型註冊到admin中,就能夠實現.ajax

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()來將自定義的類和模型註冊在一塊兒.django

註冊方式有兩種,一種是使用類裝飾器,一種是使用siteapp

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源碼中的屬性有:ide

# 在列表頁顯示的字段,默認會顯示全部字段,有對應的方法能夠重寫
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中,須要是一個方法post

# 定製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文件,來指定給某個模板頁面

# 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的數據時添加

{% if app_name in request.path %}
    <script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"></script>
<div>
<fieldset class="custom">

<div id="div"></div>
</fieldset>
{% endif %}
複製代碼

結合form表單

django admin結合form表單,重寫fieldset.html來實現數據詳情頁面的深度自定義,經過處理form表單提交的數據,來實現後臺功能的徹底自定義。

django的admin中能夠指定form類,來自定義顯示的內容

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類

class CandidateTagAdmin(admin.ModelAdmin):
    list_display = [
        'id',
        'tag_count',
    ]
    form = CustomAddForm
複製代碼

自定義列表頁來源

除了能夠經過修改admin的屬性,來實現列表頁展現字段的自定義,也能夠對列表頁數據進行篩選,例如,篩選出活躍的用戶等,這個能夠在action中定義新的方法

也能夠重寫admin中的get_queryset方法,返回的qs是從新篩選以後的數據,能夠避免一些業務邏輯上的誤操做

這裏的代碼展現了,在列表頁,展現其餘表中的數據,註冊模型表的數據沒有展現

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方法

重寫這個方法:

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標籤,直接渲染

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 = '所屬部門'
複製代碼
相關文章
相關標籤/搜索