咱們知道在models.py文件中建立的數據表,一方面咱們能夠經過視圖函數對其進行增刪改查,一方面咱們也能夠經過admin進行,一般咱們是經過admin的前端頁面進行增刪改查。這裏咱們在後端admin.py文件中進行。html
用admin對數據表的操做都須要在每一個APP項目中的admin.py文件中將你須要處理的表名admin.site.register(表名)導入前端
建立OK後如今進入admin的頁面進行操做:django
經過admin對UserInfo表進行增刪改查可知其url的變化的規律以下所示:後端
自動生成URL /admin/app01/userinfo/ 列表 change_list_view /admin/app01/userinfo/add/ 增長 方法 /admin/app01/userinfo/2/change/ 修改 方法 /admin/app01/userinfo/2/delete/ 刪除 方法
執行到這一步咱們會有疑問,如此多的url,而在Django的url的配置文件中卻只有下面這行代碼:app
from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), ]
這裏咱們猜測在執行路由分發以前url(r'^admin/', admin.site.urls),它必定先作了什麼事。ide
1.單字段顯示字段文本名:svg
class UserInfo(models.Model): name = models.CharField(max_length=32) email = models.EmailField(max_length=32) def __str__(self): return self.name
效果以下圖所示:函數
2.多字段文本顯示:ui
admin在__str__的默認方式中提供的只有單字段的文本顯示,可是經過admin.py文件咱們能夠自定義多字段的文本顯示以下:this
from django.contrib import admin from . import models class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 admin.site.register(models.UserInfo,foo) #表示在admin在處理UserInfo中執行foo中的方法
執行後的效果以下圖所示:
這裏咱們須要注意的是list_display這個列表中的字段既能夠是數據表中既有的字段也能夠是自定義的字段,以下代碼便可實現:
from django.contrib import admin from . import models class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email','whatmini'] #list_display即在admin的頁面中顯示的字段 def whatmini(self,obj): #自定義顯示的字段 return "hello" admin.site.register(models.UserInfo,foo) #表示在admin在處理UserInfo中執行foo中的方法
執行的效果以下圖所示:
當須要自定義字段顯示時,須要建立以顯示字段爲函數名的函數,並帶有return值的函數,上述whatmini代碼中的另外一個參數obj,是當前數據對象
以下將代碼修改執行:
def whatmini(self,obj): #自定義顯示的字段 print(obj) return obj.name
下面是執行的結果
October 18, 2017 - 16:48:24 Django version 1.11.4, using settings 'lijianCrm.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK. UserInfo object UserInfo object
下面是前端admin頁面的顯示效果:
因此經過這個自定義的咱們能夠作不少的事情如能夠將字段變成a標籤:
from django.contrib import admin from . import models from django.utils.safestring import mark_safe class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email','whatmini'] #list_display即在admin的頁面中顯示的字段 def whatmini(self,obj): #自定義顯示的字段 tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name) return mark_safe(tp1) admin.site.register(models.UserInfo,foo) #表示在admin在處理UserInfo中執行foo中的方法
admin前端頁面顯示效果以下:
須要瞭解的是,admin.ModelAdmin是admin對每一個數據表執行的一個默認的配置,其源碼以下
register源碼:
經過register的源碼能夠知道 model_or_iterable這個參數能夠是列表
def register(self, model_or_iterable, admin_class=None, **options): """ Registers the given model(s) with the given admin class. The model(s) should be Model classes, not instances. If an admin class isn't given, it will use ModelAdmin (the default admin options). If keyword arguments are given -- e.g., list_display -- they'll be applied as options to the admin class. If a model is already registered, this will raise AlreadyRegistered. If a model is abstract, this will raise ImproperlyConfigured. """ if not admin_class: admin_class = ModelAdmin if isinstance(model_or_iterable, ModelBase): #當model_or_iterable 是列表時執行下面代碼 model_or_iterable = [model_or_iterable]
便可以在admin.py中的代碼能夠改爲下面操做:
class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email','whatmini'] #list_display即在admin的頁面中顯示的字段 def whatmini(self,obj): #自定義顯示的字段 tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name) return mark_safe(tp1) admin.site.register([models.UserInfo,"第二張表","第三張表",....],foo) #表示在admin在處理UserInfo中執行foo中的方法
這裏三張表均可以執行foo函數的方法。
同時也能夠經過裝飾器的方式進行:
from django.contrib import admin from . import models from django.utils.safestring import mark_safe @admin.register(models.UserInfo) class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email','whatmini'] #list_display即在admin的頁面中顯示的字段 def whatmini(self,obj): #自定義顯示的字段 tp1= "<a href=http://www.cnblogs.com/lijian-22huxiaoshan/>{0}</a>".format(obj.name) return mark_safe(tp1)
ModelAdmin源碼:
3.list_display_links方法:
list_display_links,列表時,定製列能夠點擊跳轉。
from django.contrib import admin from . import models from django.utils.safestring import mark_safe class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] admin.site.register(models.UserInfo,foo) #表示在admin在處理UserInfo中執行foo中的方法
4.list_filter,列表時,定製右側快速篩選
from django.contrib import admin from . import models from django.utils.safestring import mark_safe class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] list_filter = ['name','group'] admin.site.register(models.UserInfo,foo) #表示在admin在處理UserInfo中執行foo中的方法 admin.site.register(models.UserGroup)
當這裏的UserInfo和第三張表進行ForeignKey關聯時也會將第三張表的數據顯示以下:
也能夠經過下面的代碼進行定製:
from django.contrib import admin from . import models from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] class Ugg(admin.SimpleListFilter): title = _('角色組') parameter_name = 'xxxxxx' def lookups(self, request, model_admin): """ 顯示篩選選項 :param request: :param model_admin: :return: """ return models.UserGroup.objects.values_list('id', 'title') #前端顯示的篩選條件 def queryset(self, request, queryset): """ 點擊查詢時,進行篩選 :param request: :param queryset: :return: """ v = self.value() return queryset list_filter = ['name',Ugg] admin.site.register(models.UserInfo,foo) #表示在admin在處理UserInfo中執行foo中的方法 admin.site.register(models.UserGroup)
5.list_select_related,列表時,連表查詢是否自動select_related
6.分頁
# 分頁,每頁顯示條數 list_per_page = 100 # 分頁,顯示所有(真實數據<該值時,纔會有顯示所有) list_max_show_all = 200 # 分頁插件 paginator = Paginator
7.list_editable,列表時,能夠編輯的列
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): list_display = ('user', 'pwd','ug',) list_editable = ('ug',)
8.search_fields,列表時,模糊搜索的功能
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): search_fields = ('user', 'pwd')
9.date_hierarchy,列表時,對Date和DateTime類型進行搜索
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): date_hierarchy = 'ctime'
須要注意的是該方法須要數據表中有時間的字段
10.preserve_filters,詳細頁面,刪除、修改,更新後跳轉回列表後,是否保留原搜索條件
11.save_as = False,詳細頁面,按鈕爲「Sava as new」 或 「Sava and add another」
12.save_as_continue = True,點擊保存並繼續編輯
save_as_continue = True
# 若是 save_as=True,save_as_continue = True, 點擊Sava as new 按鈕後繼續編輯。 # 若是 save_as=True,save_as_continue = False,點擊Sava as new 按鈕後返回列表。 New in Django 1.10.
13.save_on_top = False,詳細頁面,在頁面上方是否也顯示保存刪除等按鈕
14.inlines,詳細頁面,若是有其餘表和當前表作FK,那麼詳細頁面能夠進行動態增長和刪除
class UserInfoInline(admin.StackedInline): # TabularInline這個也能夠繼承功能和StackedInline的功能同樣只是顯示方式不一樣而已 extra = 0 model = models.UserInfo class UserGroupAdmin(admin.ModelAdmin): list_display = ['title',] inlines = [UserInfoInline, ] admin.site.register(models.UserGroup,UserGroupAdmin)
admin前端頁面的顯示效果以下:
這裏須要注意的是,ForeignKey字段在在哪一個表則上述代碼只能關聯另外的表不能關聯FK字段所在的那張表
15.action,列表時,定製action中的操做
代碼以下:
class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] def func(self,request,queryset): pass actions = [func,]
因此這裏經過func咱們能夠作自定義的操做以下:
class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] def func(self,request,queryset): print(request.POST.getlist('_selected_action')) print('代碼來了') actions = [func,] func.short_description = "中文顯示自定義Actions"
執行結果:
[18/Oct/2017 19:26:58] "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 304 0 ['2', '1'] 代碼來了 [18/Oct/2017 19:27:08] "POST /admin/app01/userinfo/ HTTP/1.1" 302 0
16.定製HTML模板
change_list_template頁面
除了change_list_template頁面admin中還有如下頁面:
add_form_template = None #添加頁面 change_form_template = None #編輯頁面 delete_confirmation_template = None #刪除頁面 delete_selected_confirmation_template = None #刪除確認頁面 object_history_template = None #刪除顯示記錄頁面
17.raw_id_fields,詳細頁面,針對FK和M2M字段變成以Input框形式
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): raw_id_fields = ('FK字段', 'M2M字段',)
18.fields,詳細頁面時,顯示字段的字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fields = ('user',)
19.exclude,詳細頁面時,排除的字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): exclude = ('user',)
20.readonly_fields,詳細頁面時,只讀字段
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): readonly_fields = ('user',)
21.fieldsets,詳細頁面時,使用fieldsets標籤對數據進行分割顯示
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): fieldsets = ( ('基本數據', { 'fields': ('user', 'pwd', 'ctime',) }), ('其餘', { 'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty' 'fields': ('user', 'pwd'), }), )
22.詳細頁面時,M2M顯示時,數據移動選擇(方向:上下和左右)
代碼以下:
class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] def func(self,request,queryset): print(request.POST.getlist('_selected_action')) print('代碼來了') actions = [func,] func.short_description = "中文顯示自定義Actions" filter_horizontal = ("roles",)
這裏須要注意關聯數據表要有ManyToManyField的字段
23.ordering,列表時,數據排序規則
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): ordering = ('-id',) 或 def get_ordering(self, request): return ['-id', ] #從小到大排
24.view_on_site,編輯時,是否在頁面上顯示view on set
class foo(admin.ModelAdmin): #自定義須要繼承admin.ModelAdmin list_display = ['name','email'] #list_display即在admin的頁面中顯示的字段 list_display_links = ['name','email'] def func(self,request,queryset): print(request.POST.getlist('_selected_action')) print('代碼來了') actions = [func,] func.short_description = "中文顯示自定義Actions" filter_horizontal = ("roles",) def view_on_site(self,obj): return 'https://www.baidu.com'
25.radio_fields,詳細頁面時,使用radio顯示選項(FK默認使用select)
radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL
26.show_full_result_count = True,列表時,模糊搜索後面顯示的數據個數樣式
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): # show_full_result_count = True # 1 result (12 total) # show_full_result_count = False # 1 result (Show all) search_fields = ('user',)
27.formfield_overrides = {},詳細頁面時,指定現實插件
from django.forms import widgets from django.utils.html import format_html class MyTextarea(widgets.Widget): def __init__(self, attrs=None): # Use slightly better defaults than HTML's 20x2 box default_attrs = {'cols': '40', 'rows': '10'} if attrs: default_attrs.update(attrs) super(MyTextarea, self).__init__(default_attrs) def render(self, name, value, attrs=None): if value is None: value = '' final_attrs = self.build_attrs(attrs, name=name) return format_html('<textarea {}>\r\n{}</textarea>',final_attrs, value) @admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): formfield_overrides = { models.models.CharField: {'widget': MyTextarea}, }
28.prepopulated_fields = {},添加頁面,當在某字段填入值後,自動會將值填充到指定字段。
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): prepopulated_fields = {"email": ("user","pwd",)}
29.form = ModelForm,用於定製用戶請求時候表單驗證
from app01 import models from django.forms import ModelForm from django.forms import fields class MyForm(ModelForm): others = fields.CharField() class Meta: model = models = models.UserInfo fields = "__all__" @admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): form = MyForm
30.empty_value_display = "列數據爲空時,顯示默認值"
@admin.register(models.UserInfo) class UserAdmin(admin.ModelAdmin): empty_value_display = "列數據爲空時,默認顯示" list_display = ('user','pwd','up') def up(self,obj): return obj.user up.empty_value_display = "指定列數據爲空時,默認顯示"