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

一.Django admin的内部依赖:

依赖的app

  1. django.contrib.auth
  2. django.contrib.contenttypes
  3. django.contrib.messages
  4. django.contrib.sessions

模版:

  1. django.contrib.auth.context_processors.auth
  2. django.contrib.messages.context_processors.messages

中间件:

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

二:配置路由

  1. from django.conf.urls import url,include
  2. from django.contrib import admin
  3.  
  4. urlpatterns = [
  5. url(r'^admin/', admin.site.urls),
  6. ]

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

/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/

  1. class AdminSite(object):
  2. """
  3. An AdminSite object encapsulates an instance of the Django admin application, ready
  4. to be hooked in to your URLconf. Models are registered with the AdminSite using the
  5. register() method, and the get_urls() method can then be used to access Django view
  6. functions that present a full admin interface for the collection of registered
  7. models.
  8. """
  9.  
  10. # Text to put at the end of each page's <title>.
  11. site_title = ugettext_lazy('Django site admin')
  12.  
  13. # Text to put in each page's <h1>.
  14. site_header = ugettext_lazy('Django administration')
  15.  
  16. # Text to put at the top of the admin index page.
  17. index_title = ugettext_lazy('Site administration')
  18.  
  19. # URL for the "View site" link at the top of each admin page.
  20. site_url = '/'
  21.  
  22. _empty_value_display = '-'
  23.  
  24. login_form = None
  25. index_template = None
  26. app_index_template = None
  27. login_template = None
  28. logout_template = None
  29. password_change_template = None
  30. password_change_done_template = None
  31.  
  32. def __init__(self, name='admin'):
  33. self._registry = {} # model_class class -> admin_class instance
  34. self.name = name
  35. self._actions = {'delete_selected': actions.delete_selected}
  36. self._global_actions = self._actions.copy()
  37. all_sites.add(self)
  38.  
  39. def register(self, model_or_iterable, admin_class=None, **options):
  40. """
  41. Registers the given model(s) with the given admin class.
  42.  
  43. The model(s) should be Model classes, not instances.
  44.  
  45. If an admin class isn't given, it will use ModelAdmin (the default
  46. admin options). If keyword arguments are given -- e.g., list_display --
  47. they'll be applied as options to the admin class.
  48.  
  49. If a model is already registered, this will raise AlreadyRegistered.
  50.  
  51. If a model is abstract, this will raise ImproperlyConfigured.
  52. """
  53. if not admin_class:
  54. admin_class = ModelAdmin
  55.  
  56. if isinstance(model_or_iterable, ModelBase):
  57. model_or_iterable = [model_or_iterable]
  58. for model in model_or_iterable:
  59. if model._meta.abstract:
  60. raise ImproperlyConfigured(
  61. 'The model %s is abstract, so it cannot be registered with admin.' % model.__name__
  62. )
  63.  
  64. if model in self._registry:
  65. raise AlreadyRegistered('The model %s is already registered' % model.__name__)
  66.  
  67. # Ignore the registration if the model has been
  68. # swapped out.
  69. if not model._meta.swapped:
  70. # If we got **options then dynamically construct a subclass of
  71. # admin_class with those **options.
  72. if options:
  73. # For reasons I don't quite understand, without a __module__
  74. # the created class appears to "live" in the wrong place,
  75. # which causes issues later on.
  76. options['__module__'] = __name__
  77. admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
  78.  
  79. # Instantiate the admin class to save in the registry
  80. self._registry[model] = admin_class(model, self)
  81.  
  82. def get_urls(self):
  83. from django.conf.urls import url, include
  84. # Since this module gets imported in the application's root package,
  85. # it cannot import models from other applications at the module level,
  86. # and django.contrib.contenttypes.views imports ContentType.
  87. from django.contrib.contenttypes import views as contenttype_views
  88.  
  89. def wrap(view, cacheable=False):
  90. def wrapper(*args, **kwargs):
  91. return self.admin_view(view, cacheable)(*args, **kwargs)
  92. wrapper.admin_site = self
  93. return update_wrapper(wrapper, view)
  94.  
  95. # Admin-site-wide views.
  96. urlpatterns = [
  97. url(r'^$', wrap(self.index), name='index'),
  98. url(r'^login/$', self.login, name='login'),
  99. url(r'^logout/$', wrap(self.logout), name='logout'),
  100. url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
  101. url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
  102. name='password_change_done'),
  103. url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
  104. url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
  105. name='view_on_site'),
  106. ]
  107.  
  108. # Add in each model's views, and create a list of valid URLS for the
  109. # app_index
  110. valid_app_labels = []
  111. for model, model_admin in self._registry.items():
  112. urlpatterns += [
  113. url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
  114. ]
  115. if model._meta.app_label not in valid_app_labels:
  116. valid_app_labels.append(model._meta.app_label)
  117.  
  118. # If there were ModelAdmins registered, we should have a list of app
  119. # labels for which we need to allow access to the app_index view,
  120. if valid_app_labels:
  121. regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$'
  122. urlpatterns += [
  123. url(regex, wrap(self.app_index), name='app_list'),
  124. ]
  125. return urlpatterns
  126.  
  127. @property
  128. def urls(self):
  129. return self.get_urls(), 'admin', self.name

源码摘要参考

  1. option.py BaseModelAdmin
  2.  
  3. def get_urls(self):
  4. from django.conf.urls import url
  5.  
  6. def wrap(view):
  7. def wrapper(*args, **kwargs):
  8. return self.admin_site.admin_view(view)(*args, **kwargs)
  9. wrapper.model_admin = self
  10. return update_wrapper(wrapper, view)
  11.  
  12. info = self.model._meta.app_label, self.model._meta.model_name
  13.  
  14. urlpatterns = [
  15. url(r'^$', wrap(self.changelist_view), name='%s_%s_changelist' % info),
  16. url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info),
  17. url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info),
  18. url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info),
  19. url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
  20. # For backwards compatibility (was the change url before 1.9)
  21. url(r'^(.+)/$', wrap(RedirectView.as_view(
  22. pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info)
  23. ))),
  24. ]
  25. return urlpatterns
  26.  
  27. @property
  28. def urls(self):
  29. return self.get_urls()

源码参考2

三:定制admin

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

  1. admin.site.register(UserInfo)

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

1.应用方式:

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

2.定制功能:

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

   list_display 有四种赋值方式:

  1. #模型的字段
  2. class PersonAdmin(admin.ModelAdmin):
  3. list_display = ('first_name', 'last_name')
  4. #一个接受对象实例作为参数的可调用对象
  5. def upper_case_name(obj):
  6. return ("%s %s" % (obj.first_name, obj.last_name)).upper()
  7. upper_case_name.short_description = 'Name'
  8.  
  9. class PersonAdmin(admin.ModelAdmin):
  10. list_display = (upper_case_name,)
  11.  
  12. #一个表示ModelAdmin 中某个属性的字符串。行为与可调用对象相同
  13. class PersonAdmin(admin.ModelAdmin):
  14. list_display = ('upper_case_name',)
  15.  
  16. def upper_case_name(self, obj):
  17. return ("%s %s" % (obj.first_name, obj.last_name)).upper()
  18. upper_case_name.short_description = 'Name'
  19.  
  20. #表示模型中某个属性的字符串。它的行为与可调用对象几乎相同,但这时的self 是模型实例。
  21. from django.db import models
  22. from django.contrib import admin
  23.  
  24. class Person(models.Model):
  25. name = models.CharField(max_length=50)
  26. birthday = models.DateField()
  27.  
  28. def decade_born_in(self):
  29. return self.birthday.strftime('%Y')[:3] + "0's"
  30. decade_born_in.short_description = 'Birth decade'
  31.  
  32. class PersonAdmin(admin.ModelAdmin):
  33. list_display = ('name', 'decade_born_in')

list_display 数据类型

实例:

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

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

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

  1. #字段名称,其指定的字段应该是BooleanField、CharField、DateField、DateTimeField、#IntegerField、ForeignKey 或ManyToManyField,
  2. class UserAdmin(admin.ModelAdmin):
  3. list_filter = ('group','roles')
  4.  
  5. #list_filter 中的字段名称也可以使用__ 查找跨关联关系
  6. list_filter = ('group__title','roles')
  7.  
  8. #一个继承自django.contrib.admin.SimpleListFilter 的类,你需要给它提供title 和 parameter_name 属性来重写lookups 和queryset 方法
  9.  
  10. from django.contrib import admin
  11. from app01.models import *
  12. from django.utils.safestring import mark_safe
  13. from django.utils.translation import ugettext_lazy as _
  14.  
  15. class Ugg(admin.SimpleListFilter):
  16. title = _('decade born')
  17. parameter_name = 'xxxxxx'
  18.  
  19. def lookups(self, request, model_admin):
  20. """
  21. 显示筛选选项
  22. :param request:
  23. :param model_admin:
  24. :return:
  25. """
  26. return UserGroup.objects.values_list('id', 'title')
  27.  
  28. def queryset(self, request, queryset):
  29. """
  30. 点击查询时,进行筛选
  31. :param request:
  32. :param queryset:
  33. :return:
  34. """
  35. v = self.value()
  36. return queryset
  37.  
  38. list_filter = ('group',Ugg)
  39. #一个元组,第一个元素是字段名称,第二个元素是从继承自django.contrib.admin.FieldListFilter 的一个类
  40.  
  41. class PersonAdmin(admin.ModelAdmin):
  42. list_filter = (
  43. ('is_staff', admin.BooleanFieldListFilter),
  44. )

list_filter 数据类型

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

  1. list_select_related = ['group']

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

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

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

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

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

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

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

          prepopulated_fields不接受DateTimeFieldForeignKeyManyToManyField字段。

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

  1. list_editable = ('name',)

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

  1. 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标签对数据进行分组显示

  1. fieldsets = (
  2. ('基本数据', {
  3. 'fields': ('name', )
  4. }),
  5. ('其他', {
  6. 'classes': ('collapse', 'wide', 'extrapretty'), # 'collapse','wide', 'extrapretty'
  7. 'fields': ('email','group',),
  8. }),
  9. )

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

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

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

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

  1. class UserInfoInline(admin.StackedInline): # TabularInline
  2. extra = 0
  3. model = UserInfo
  4.  
  5. class UserGropuAdmin(admin.ModelAdmin):
  6. inlines = [UserInfoInline,]

action  定制action中的操作

  1. def func(self, request, queryset): (必须有requestqueryset参数)
  2. print(self, request, queryset)
  3. print(request.POST.getlist('_selected_action'))
  4.  
  5. func.short_description = "中文显示自定义Actions"
  6. actions = [func, ]
  7.  
  8. # Action选项都是在页面上方显示
  9. actions_on_top = True
  10. # Action选项都是在页面下方显示
  11. actions_on_bottom = False
  12.  
  13. # 是否显示选择个数
  14. actions_selection_counter = True

  在整个站点应用该操作:

  1. from django.contrib import admin
  2.  
  3. admin.site.add_action(fund)

  为全局ModelAdmin禁用某个操作 

  1. admin.site.disable_action('delete_selected')

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

  1. class MyModelAdmin(admin.ModelAdmin):
  2. actions = None

  按需启用或禁用操作

  1. class MyModelAdmin(admin.ModelAdmin):
  2. ...
  3.  
  4. def get_actions(self, request):
  5. actions = super(MyModelAdmin, self).get_actions(request)
  6. if request.user.username[0].upper() != 'J':
  7. if 'delete_selected' in actions:
  8. del actions['delete_selected']
  9. return actions

定制HTML模板

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

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

  1. add_form_template = None
  2. change_form_template = None
  3. change_list_template = None
  4. delete_confirmation_template = None
  5. delete_selected_confirmation_template = None
  6. object_history_template = None

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

  1. view_on_site = False

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

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

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

show_full_result_count = True,列表时,模糊搜索后面显示的数据个数样式

  1. @admin.register(models.UserInfo)
  2. class UserAdmin(admin.ModelAdmin):
  3. # show_full_result_count = True # 1 result (12 total)
  4. # show_full_result_count = False # 1 result (Show all)
  5. search_fields = ('user',)

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

empty_value_display = "列数据为空时,显示默认值"

  1. @admin.register(models.UserInfo)
  2. class UserAdmin(admin.ModelAdmin):
  3. empty_value_display = "列数据为空时,默认显示"
  4.  
  5. list_display = ('user','pwd','up')
  6.  
  7. def up(self,obj):
  8. return obj.user
  9. up.empty_value_display = "指定列数据为空时,默认显示"
  10.   

 

  1.   

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. ubuntu终端使用代理

    sudo http_proxy=http://your_proxy:proxy_port dropbox start -i or sudo https_proxy=http://your_proxy: ...

  2. Linux服务器 大量的CLOSE_WAIT、TIME_WAIT解决办法

    http://itindex.net/detail/50213-%E6%9C%8D%E5%8A%A1%E5%99%A8-time_wait-close_wait http://itindex.net/ ...

  3. 在odl中怎样实现rpc

    opendaylight作为sdn主要开源项目,採用osgi框架.已经得到非常多厂商的支持.氦版本号也公布在即. 以下介绍一下在odl中怎样实现rpc. odl使用yang作为model模型定义文件. ...

  4. django用户认证系统——自定义认证后台8

    Django auth 应用默认支持用户名(username)进行登录.但是在实践中,网站可能还需要邮箱.手机号.身份证号等进行登录,这就需要我们自己写一个认证后台,用于验证用户输入的用户信息是否正确 ...

  5. iOS开发之--制作属于自己的frameWork

    开发的时候,有时候,我们会遇到协同开发,在协同开发的时候,每个开发者都会创建自己的工具类,还有就是当一个项目需要嵌套到另一个项目里面,这些时候,如果能把所需的部分打包成framework,会方便很多, ...

  6. java was started but returned exit code=1

    将eclipse.ini文件删掉, 重启eclipse 会自动生成一个eclipse.ini就可以了~

  7. location.assign 与 location.replace的区别

    window.location.assign(url) : 加载 URL 指定的新的 HTML 文档. 就相当于一个链接,跳转到指定的url,当前页面会转为新页面内容,可以点击后退返回上一个页面. w ...

  8. GetDesktopWindow和GetWindow区别

    GetWindow The GetWindow function retrieves a handle to a window that has the specified relationship ...

  9. 下载flv格式视频

    我们再看flash plaer播放视频时,有些时候需要下载,无奈找不到下载的按钮.这时,我们可以用以下的方式来进行下载. 其它格式估计也是有迹可循,大家仔细看看网页源代码,看到类似于这种地址,看到有相 ...

  10. poj 1182 食物链 (带关系的并查集)

      食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44835 Accepted: 13069 Description 动 ...