咱们知道在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 = "指定列数据为空时,默认显示"