Django 内置的admin是对于model中对应的数据表进行增删改查提供的组建

一.Django admin的内部依赖:

依赖的app

django.contrib.auth
django.contrib.contenttypes
django.contrib.messages
django.contrib.sessions

模版:

 django.contrib.auth.context_processors.auth
django.contrib.messages.context_processors.messages

中间件:

 django.contrib.auth.middleware.AuthenticationMiddleware
django.contrib.messages.middleware.MessageMiddleware

二:配置路由

from django.conf.urls import url,include
from django.contrib import admin urlpatterns = [
url(r'^admin/', admin.site.urls),
]

当前配置的路由可以创建一些路由映射关系:

/admin/
/admin/login/
/admin/logout/
/admin/password_change/
/admin/password_change/done/

/admin/app名称/model名称/
/admin/app名称/model名称/add/
/admin/app名称/model名称/ID值/history/
/admin/app名称/model名称/ID值/change/
/admin/app名称/model名称/ID值/delete/

class AdminSite(object):
"""
An AdminSite object encapsulates an instance of the Django admin application, ready
to be hooked in to your URLconf. Models are registered with the AdminSite using the
register() method, and the get_urls() method can then be used to access Django view
functions that present a full admin interface for the collection of registered
models.
""" # Text to put at the end of each page's <title>.
site_title = ugettext_lazy('Django site admin') # Text to put in each page's <h1>.
site_header = ugettext_lazy('Django administration') # Text to put at the top of the admin index page.
index_title = ugettext_lazy('Site administration') # URL for the "View site" link at the top of each admin page.
site_url = '/' _empty_value_display = '-' login_form = None
index_template = None
app_index_template = None
login_template = None
logout_template = None
password_change_template = None
password_change_done_template = None def __init__(self, name='admin'):
self._registry = {} # model_class class -> admin_class instance
self.name = name
self._actions = {'delete_selected': actions.delete_selected}
self._global_actions = self._actions.copy()
all_sites.add(self) 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]
for model in model_or_iterable:
if model._meta.abstract:
raise ImproperlyConfigured(
'The model %s is abstract, so it cannot be registered with admin.' % model.__name__
) if model in self._registry:
raise AlreadyRegistered('The model %s is already registered' % model.__name__) # Ignore the registration if the model has been
# swapped out.
if not model._meta.swapped:
# If we got **options then dynamically construct a subclass of
# admin_class with those **options.
if options:
# For reasons I don't quite understand, without a __module__
# the created class appears to "live" in the wrong place,
# which causes issues later on.
options['__module__'] = __name__
admin_class = type("%sAdmin" % model.__name__, (admin_class,), options) # Instantiate the admin class to save in the registry
self._registry[model] = admin_class(model, self) def get_urls(self):
from django.conf.urls import url, include
# Since this module gets imported in the application's root package,
# it cannot import models from other applications at the module level,
# and django.contrib.contenttypes.views imports ContentType.
from django.contrib.contenttypes import views as contenttype_views def wrap(view, cacheable=False):
def wrapper(*args, **kwargs):
return self.admin_view(view, cacheable)(*args, **kwargs)
wrapper.admin_site = self
return update_wrapper(wrapper, view) # Admin-site-wide views.
urlpatterns = [
url(r'^$', wrap(self.index), name='index'),
url(r'^login/$', self.login, name='login'),
url(r'^logout/$', wrap(self.logout), name='logout'),
url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
name='password_change_done'),
url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
name='view_on_site'),
] # Add in each model's views, and create a list of valid URLS for the
# app_index
valid_app_labels = []
for model, model_admin in self._registry.items():
urlpatterns += [
url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
]
if model._meta.app_label not in valid_app_labels:
valid_app_labels.append(model._meta.app_label) # If there were ModelAdmins registered, we should have a list of app
# labels for which we need to allow access to the app_index view,
if valid_app_labels:
regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$'
urlpatterns += [
url(regex, wrap(self.app_index), name='app_list'),
]
return urlpatterns @property
def urls(self):
return self.get_urls(), 'admin', self.name

源码摘要参考

 option.py  BaseModelAdmin类

def get_urls(self):
from django.conf.urls import url def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
wrapper.model_admin = self
return update_wrapper(wrapper, view) info = self.model._meta.app_label, self.model._meta.model_name urlpatterns = [
url(r'^$', wrap(self.changelist_view), name='%s_%s_changelist' % info),
url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info),
url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info),
url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info),
url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
# For backwards compatibility (was the change url before 1.9)
url(r'^(.+)/$', wrap(RedirectView.as_view(
pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info)
))),
]
return urlpatterns @property
def urls(self):
return self.get_urls()

源码参考2

三:定制admin

在admin.py中只需注册某个类,即可在admin中实现增删改查的功能。

admin.site.register(UserInfo)

为类定制更多的信息,需为其定制modelAdmin

1.应用方式:

#方式一:装饰器
@admin.register(UserInfo)
class UserAdmin(admin.ModelAdmin):
list_display = ['name','nickname','email'] #方式二:参数传入
# admin.site.register(UserInfo,UserAdmin)

2.定制功能:

   list_display,列表时,定制显示的列。

   list_display 有四种赋值方式:

#模型的字段
class PersonAdmin(admin.ModelAdmin):
list_display = ('first_name', 'last_name')
#一个接受对象实例作为参数的可调用对象
def upper_case_name(obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name' class PersonAdmin(admin.ModelAdmin):
list_display = (upper_case_name,) #一个表示ModelAdmin 中某个属性的字符串。行为与可调用对象相同
class PersonAdmin(admin.ModelAdmin):
list_display = ('upper_case_name',) def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name' #表示模型中某个属性的字符串。它的行为与可调用对象几乎相同,但这时的self 是模型实例。
from django.db import models
from django.contrib import admin class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField() def decade_born_in(self):
return self.birthday.strftime('%Y')[:3] + "0's"
decade_born_in.short_description = 'Birth decade' class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'decade_born_in')

list_display 数据类型

实例:

@admin.register(UserInfo)
class UserAdmin(admin.ModelAdmin):
list_display = ['name','nickname','email','xxx']
list_display_links = ('nickname',) def xxx(self,obj):
a = '<a href="www.baidu.com>点击跳转</a>'
return mark_safe(a)

  list_display_links,指定列表显示的哪列可以点击跳转,定制列可以点击跳转。

  list_filter 设置激活激活Admin 修改列表页面右侧栏中的过滤器

#字段名称,其指定的字段应该是BooleanField、CharField、DateField、DateTimeField、#IntegerField、ForeignKey 或ManyToManyField,
class UserAdmin(admin.ModelAdmin):
list_filter = ('group','roles') #list_filter 中的字段名称也可以使用__ 查找跨关联关系
list_filter = ('group__title','roles') #一个继承自django.contrib.admin.SimpleListFilter 的类,你需要给它提供title 和 parameter_name 属性来重写lookups 和queryset 方法 from django.contrib import admin
from app01.models import *
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _ class Ugg(admin.SimpleListFilter):
title = _('decade born')
parameter_name = 'xxxxxx' def lookups(self, request, model_admin):
"""
显示筛选选项
:param request:
:param model_admin:
:return:
"""
return UserGroup.objects.values_list('id', 'title') def queryset(self, request, queryset):
"""
点击查询时,进行筛选
:param request:
:param queryset:
:return:
"""
v = self.value()
return queryset list_filter = ('group',Ugg)
#一个元组,第一个元素是字段名称,第二个元素是从继承自django.contrib.admin.FieldListFilter 的一个类 class PersonAdmin(admin.ModelAdmin):
list_filter = (
('is_staff', admin.BooleanFieldListFilter),
)

list_filter 数据类型

list_select_related,设置list_select_related以告诉Django在检索管理更改列表页面上的对象列表时使用  select_ralated。这可以节省大量的数据库查询。该值应该是布尔值,列表或元组。默认值为False

list_select_related = ['group']

  list_max_show_all 控制在“显示所有”管理更改列表页面上可以显示的项目数,默认情况下,设置为200

  list_per_page. 设置控制Admin 修改列表页面每页中显示多少项。默认设置为100

  ordering以指定如何在Django管理视图中对对象列表进行排序

 ordering = ['-id', ]. 从大到小
ordering = ['id', ]. 从小到大

  paginator 默认情况下,使用django.core.paginator.Paginator

  prepopulated_fields设置为将字段名称映射到其应预先填充的字段的字典:

 prepopulated_fields = {'name':('nickname','email')} #nickname 和email和name的值相同

          prepopulated_fields不接受DateTimeFieldForeignKeyManyToManyField字段。

  list_editable指定列表中可以编辑的列

list_editable = ('name',)

search_fields,模糊搜索时列表中的搜索列范围,

search_fields = ('namer', 'email')

date_hierarchy,列表时,对Date和DateTime类型进行搜索

preserve_filters,详细页面,删除、修改,更新后跳转回列表后,是否保留原搜索条件

save_as = False,详细页面,按钮为“Sava as new” 或 “Sava and add another”

save_as_continue = True,点击保存并继续编辑

save_on_top = False,详细页面,在页面上方是否也显示保存删除等按钮

fields,详细页面时,显示字段的字段

exclude,详细页面时,排除的字段

readonly_fields,详细页面时,只读字段

fieldsets,详细页面时,使用fieldsets标签对数据进行分组显示

   fieldsets = (
('基本数据', {
'fields': ('name', )
}),
('其他', {
'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty'
'fields': ('email','group',),
}),
)

多对多或一对多显示时添加数据移动选择(方向:上下和左右)

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):
filter_vertical = ("m2m字段",) # 或filter_horizontal = ("m2m字段",)

inlines,详细页面,如果有其他表和当前表做FK,那么详细页面可以进行动态增加和删除

inlines 关联的类必须继承:StackedInline,且放在外键的类里

class UserInfoInline(admin.StackedInline): # TabularInline
extra = 0
model = UserInfo class UserGropuAdmin(admin.ModelAdmin):
inlines = [UserInfoInline,]

action  定制action中的操作

  def func(self, request, queryset): (必须有request,queryset参数)
print(self, request, queryset)
print(request.POST.getlist('_selected_action')) func.short_description = "中文显示自定义Actions"
actions = [func, ] # Action选项都是在页面上方显示
actions_on_top = True
# Action选项都是在页面下方显示
actions_on_bottom = False # 是否显示选择个数
actions_selection_counter = True

  在整个站点应用该操作:

from django.contrib import admin

admin.site.add_action(fund)

  为全局ModelAdmin禁用某个操作 

admin.site.disable_action('delete_selected')

  为特定的ModelAdmin禁用所有操作ModelAdmin

class MyModelAdmin(admin.ModelAdmin):
actions = None

  按需启用或禁用操作

class MyModelAdmin(admin.ModelAdmin):
... def get_actions(self, request):
actions = super(MyModelAdmin, self).get_actions(request)
if request.user.username[0].upper() != 'J':
if 'delete_selected' in actions:
del actions['delete_selected']
return actions

定制HTML模板

  Admin模板文件位于contrib/admin/templates/admin 目录中。

为一个特定的app重写admin模板, 需要拷贝django/contrib/admin/templates/admin 目录到你刚才创       建的目录下, 并且修改它们.

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

view_on_site,编辑时,是否在页面上显示view on set

view_on_site = False

def view_on_site(self, obj):
return 'https://www.baidu.com'

radio_fields,详细页面时,使用radio显示选项(FK默认使用select)

radio_fields = {"ug": admin.VERTICAL} # 或admin.HORIZONTAL

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',)

form = ModelForm,用于定制用户请求时候表单验证

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

 

  

Django内置Admin解析的更多相关文章

  1. Django内置Admin

    Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django.contrib.contenttyp ...

  2. 框架----Django内置Admin

    Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django.contrib.contenttyp ...

  3. Django_内置Admin

    Django内置Admin   Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django.co ...

  4. 76、django之内置Admin

    本篇导航: 配置路由 定制Admin Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django ...

  5. django之内置Admin

    本篇导航: 配置路由 定制Admin Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django ...

  6. Django内置模板标签

    Django内置标签总览 可以查询下表来总览Django的内置标签: 标签 说明 autoescape 自动转义开关 block 块引用 comment 注释 csrf_token CSRF令牌 cy ...

  7. Django内置过滤器详解附代码附效果图--附全部内置过滤器帮助文档

    前言 基本环境 Django版本:1.11.8 Python版本:3.6 OS: win10 x64 本文摘要 提供了常用的Django内置过滤器的详细介绍,包括过滤器的功能.语法.代码和效果示例. ...

  8. JSON和Django内置序列化

    JSON 什么是JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 * J ...

  9. AJAX—JSON和Django内置序列化

    JSON 什么是JSON JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation) JSON 是轻量级的文本数据交换格式 JSON 独立于语言 * J ...

随机推荐

  1. Java WEB 之页面间传递特殊字符

    本文是学习网络上的文章时的总结以及自己的一点实践.感谢大家无私的分享. 昨天在做项目的时候,有一个页面间传递特殊字符的需求,查了一些资料.如今将自己的经验写出来. 首先.在前台编码 var fckPu ...

  2. Mac OSX使用隐藏文件夹

    直接修改文件夹名字,前面加个"." 小圆点就隐藏了,下去进入可以在finder图标右键点菜单“前往文件夹...",输入你文件夹的路径即可

  3. C#获取CPU编号

    //System.Management;//需要添加引用(系统自带) /// <summary> /// 获取cpu编号 /// </summary> /// <retu ...

  4. APP接口基础学习一

    PHP面向对象思想 1.客户端发送http请求到达服务器 2.服务器做出响应返回数据(XML,JSON或者其他)到达客户端 XML与JSON 的区别 1.可读性:xml胜出 2.生成数据:json胜出 ...

  5. 【转】VC下的Unicode编程

    转自http://www.leewei.org/?p=1304 UniCode简述 在Windows下用VC编程,如果编写的程序要在多种语言环境下运行(比如日文.中文.葡萄牙文等),使用VC默认的MB ...

  6. 【ARDUINO】HC-05蓝牙不配对问题

    除了刷主从之外,不配对的原因有1:已经配对其他设备,需用AT+RMAAD来移除.2.默认为蓝牙由绑定指令设置,需改为任意地址连接模式AT+CMODE=1 //#define AT 2 #define ...

  7. IIS服务中五种身份验证的灵活运用

    微软IIS服务是一项经典的Web服务,可以为广大用户提供信息发布和资源共享功能.身份认证是保证IIS服务安全的基础机制,IIS支持以下5种 Web 身份认证方法: 一.匿名身份认证 如果启用了匿名访问 ...

  8. 【转】Spring AOP 实现原理与 CGLIB 应用

    AOP(Aspect Orient Programming),作为面向对象编程的一种补充,广泛应用于处理一些具有横切性质的系统级服务,如事务管理.安全检查.缓存.对象池管理等.AOP 实现的关键就在于 ...

  9. IO 之 File 类

    位于 java.io 包 用来将文件或者文件夹封装成对象 方便对文件和文件夹的属性信息进行操作 File 对象可以作为参数传递给流的构造函数 构造函数 // 可以将一个已存在的, 或者不存在的文件或者 ...

  10. winrar命令行参数说明

    用法:     rar <命令> -<开关 1> -<开关 N> <压缩文件> <文件...> <@列表文件...> <解 ...