Admin简介:

Admin:是django的后台 管理的wed版本

我们现在models.py文件里面建几张表:

class Author(models.Model):nid = models.AutoField(primary_key=True)name=models.CharField( max_length=32)age=models.IntegerField()# 与AuthorDetail建立一对一的关系authorDetail=models.OneToOneField(to="AuthorDetail",on_delete=models.CASCADE)
class AuthorDetail(models.Model):nid = models.AutoField(primary_key=True)birthday=models.DateField()telephone=models.BigIntegerField()addr=models.CharField( max_length=64)
class Publish(models.Model):nid = models.AutoField(primary_key=True)name=models.CharField( max_length=32)city=models.CharField( max_length=32)email=models.EmailField()class Book(models.Model):nid = models.AutoField(primary_key=True)title = models.CharField( max_length=32)publishDate=models.DateField()price=models.DecimalField(max_digits=5,decimal_places=2)# 与Publish建立一对多的关系,外键字段建立在多的一方publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表authors=models.ManyToManyField(to='Author',)

然后执行数据库迁移的两条命令。

python3 manage.py makemigrations
python3 manage.py migrate

现在直接打开项目去访问admin肯定是不行的。他会提示你要先登陆。所以要先创建一个超级用户:python3 manage.py createsuperuser

然后再登陆进去,这时候发现登陆进去并不是我们创建的那些表,因为我们还没有在admin中注册。所以在app01下的admin中注册

from app01 import models
admin.site.register(models.Book,Bookconfig)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Author)
admin.site.register(models.Publish)

注册之后,然后再访问admin地址,就会发现,我们注册了那张表就会有那个。

我们会发现每个表都是一个可点 的标签。我们可以进行曾删改查:

        http://127.0.0.1:8000/admin/app02/food/     查

http://127.0.0.1:8000/admin/app02/food/add/  增

http://127.0.0.1:8000/admin/app02/food/1/change/ 改

http://127.0.0.1:8000/admin/app02/food/2/delete/  删

现在我们点击book的那张表,是这个样子:

只能看到书的名字,那我们想看到书的其他字段呢?怎么办?

找到admin.py注册的地方,我们只是在admin中注册了,现在我们加上配置类,就可以看到其他的字段了。

class Bookconfig(admin.ModelAdmin):# list_display must not be a ManyToManyField    这里面不能放多对多的字段。list_display = ['title','price','publish','publishDate'] # 设置可以显示的字段list_display_links = ['price','title','publishDate']  # 设置有链接的字段list_filter = ['title','publish', 'authors__nid','authors']  #设置过滤的条件,search_fields = ['title','price']  # 设置根据搜寻的字段,模糊查找# 进行批量操作,actionsdef patch_init(self,request,queryset):queryset.update(price=0)   # 初始化价格为0patch_init.short_description = '价格初始化' # 批量操作的名字actions = [patch_init]      # 进行批量操作

这里有一个注意的地方,就是list_filter里面可以放外键关联的字段,也可以放多对多字段。举例:就像book表多对多author表,list_filter = ['title','publish', 'authors__nid','authors']

咱们写的这个类继承 admin.ModelAdmin,而admin.ModelAdmin这是个默认配置类,也就是说这个默认配置类自己配置了这些参数,如果我们不想用默认配置类的这些参数,我们就自己写参数覆盖默认配置类的参数就行了。

然后将我们写的这个类实例对象添加进admin.site.register(models.Book,Bookconfig)就行了。
上面说的是一些常用的配置参数,下面是一些其他的参数:

ModelAdmin中提供了大量的可定制功能,如

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

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd', 'xxxxx') def xxxxx(self, obj): return "xxxxx"

2. list_display_links,列表时,定制列可以点击跳转。

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd', 'xxxxx') list_display_links = ('pwd',)

3. list_filter,列表时,定制右侧快速筛选。

4. list_select_related,列表时,连表查询是否自动select_related

5. list_editable,列表时,可以编辑的列

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):list_display = ('user', 'pwd','ug',) list_editable = ('ug',)

6. search_fields,列表时,模糊搜索的功能

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):search_fields = ('user', 'pwd')

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

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):date_hierarchy = 'ctime'

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

class UserInfoInline(admin.StackedInline): # TabularInlineextra = 0model = models.UserInfoclass GroupAdminMode(admin.ModelAdmin): list_display = ('id', 'title',) inlines = [UserInfoInline, ]

9 action,列表时,定制action中的操作

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):# 定制Action行为具体方法def func(self, 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

10 定制HTML模板

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

11 raw_id_fields,详细页面,针对FK和M2M字段变成以Input框形式

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):raw_id_fields = ('FK字段', 'M2M字段',)

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

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):fields = ('user',)

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

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):exclude = ('user',)

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

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):readonly_fields = ('user',)

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

16 详细页面时,M2M显示时,数据移动选择(方向:上下和左右)

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

17 ordering,列表时,数据排序规则

@admin.register(models.UserInfo)
class UserAdmin(admin.ModelAdmin):ordering = ('-id',) 或 def get_ordering(self, request): return ['-id', ]

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

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

19 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

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

这里就涉及到我们之前学的类的知识了。我们一起来回顾一下:

Class A(object):X = 10
Class B(A):X = 8  # 类变量   存在类里
.b = B()
Print(b.x)

这个结果是什么呢?答案肯定是8

# class A(object):
#     x=10
#     y=12
#
# class B(A):
#     def __init__(self):   # 实例变量  存在实例里
#         self.y=10
#     x=8
#     y=20
#
# b=B()
# print(b.x)
# print(b.y) 这个答案是多少?

答案是8和10,那如果这样呢?

# class A(object):
#     def __init__(self):
#         self.y=10
#     x=10
#     y=12
# class B(A):
#     x=8
#     y=20
# b=B()
# print(b.y)
# print(b.x)     答案仍然是8和10    为什么呢?

这里面一定要区分类存储和实例存储的关系,先在实例空间中寻找,再找类空间,一个实例对象在存储的时候 先在自己的实例空间里寻找,如果找不到就从父类的实例空间中寻找,如果找不到,就在自己的类空间中寻找,然后再父的类空间中寻找。说白了,就是实例化一个对象时,要先执行__init__实例初始化,如果自己的类中没有__init__就去父类中去实例初始化。然后在类空间中寻找。

上面只是说了admin的使用,接下来我们来看一下admin的源码,看一下他是怎么工作的,我们先来复习一下单例模式。

什么是单例模式:

单例模式(Singleton Pattern是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。他可以实例化多次,但都属于着一个类的,当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

在 Python 中,我们可以用多种方法来实现单例模式:

  • 使用模块
  • 使用 __new__
  • 使用装饰器(decorator)
  • 使用元类(metaclass)

1.使用 __new__

class Singleton(object):_instance = Nonedef __new__(cls, *args, **kw):   #实例化的时候,执行__init__之前if not cls._instance:cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) return cls._instances1 = Singleton()s2 = Singleton()

s1实例化之后,先走__new__,_instance默认为none,进入if判断,重新对cls.instance进行赋值,赋值的结果是执行了object类的__new__方法,其实就是拿到了一个实例化对象。最后返回cls.instance。

此时此刻,cls.instance的值就是object类实例化的那个对象。

S2实例化之后,走__new__,但是这时候,cls.instance已经有值了,所以不会再走if判断。直接返回。

所以两次实例化都是指向s1的内存空间。S1和s2是完全一样的。这就是__new__的思路。

2.使用模块

我们先创建一个main.py文件,在创建一个func.py文件。

大家觉得这两个id一样吗?答案是一样的

第二次导入的时候不会再执行func文件了,直接实例化,因为第一次已经导入过了。

在创建一个cal文件夹

大家看这个执行结果呢?这个结果肯定是一样的

只要导入一次,在整个程序中不管在调用多少次,他都不会在执行导入的那个模块中的内容,都是直接使用的。记住这句话就行了。

还有一个例子:

这个打印结果是什么?答案是三者的id都不一样。虽然他们都是用的同一个类但是实例化出了三个对象。

Admin源码是分为三部分:启动,注册阶段,设计url,

先看注册,admin.site.register(models.Book,Bookconfig)  我们需要重点了解一下site是什么,register方法中写了什么,以及models.Book,Bookconfig  这两个参数代表什么意思?

接下来我们看一下源码:

第一步:启动

数据库迁移完成之后,我们只在admin中xie了这些代码:

admin.site.register(models.Book,)
admin.site.register(models.AuthorDetail)
admin.site.register(models.Author)
admin.site.register(models.Publish)

django启动过程中,一定会先去加载settings中的INSTALL_APPS,拿INSTALL_APPS的第一个来说,'django.contrib.admin',这句话和 from django.contrib import admin的意思是一样的,加载的时候他会去加载from django.contrib import admin

点进去admin,这时候会执行from django.contrib.admin.sites import AdminSite, site。然后点进去sites,会发现有这么一行site = AdminSite()。这就是用到了单例模式。意思就是说,只要引入site模块,就实例化AdminSite这么一个对象。然后会执行

def autodiscover():
autodiscover_modules('admin', register_to=site)

这句话的意思是告诉django启动后先会执行app下的admin.py文件。

第二步:注册

运行app下的admin.py文件,只要遇到admin.site就是实例化一个site单例对象。

admin.site.register(models.Publish)

class Publishconfig(admin.ModelAdmin): pass

admin.site.register(models.Publish,Publishconfig)这是两种注册方法,不过是多了一个我们自己添加的类

接下来就是看register方法了:(这个register方法是site = AdminSite()类中的方法)点进去

我们只看两句话:第一句:

第二个参数默认是none,意思是可以不传这个参数,如果admin_class不传,就admin_class就等于Modeladmin。如果传第二个参数,就用的是自己的那个类,所以我们写的那个类要继承Modeladmin。

第二句:

self._registry[model] = admin_class(model, self)

这个_registry是在上面初始化的时候,赋值给_register一个空的字典。

def __init__(self, name='admin'):
self._registry = {}

所谓的注册功能就是在全局的单例对象的_registry字典里面添加键值对,以model为键,以 admin_class为值。而 admin_class就是第一句我们自己写的类或者默认类的一个实例对象

所以,admin.site.register(models.Publish)这句话执行完self._registry里就有一个Publish键值对了

在当我们注册admin.site.register(models.Author)的时候,self._registry里就会多一个Author键值对了。

我们可以打印一下print(admin.site._register)看看里面有几个键值对。在admin中注册了几个就有几个键值对。

可以根据下面的源码缕一缕:

解析admin的源码:
        1 启动
           django启动后,会加载settings中的install_app
           admin.py:
                from django.contrib.admin.sites import AdminSite, site
                autodiscover_modules('admin', register_to=site):加载每一个app下的admin.py文件
        
        2 注册
        
          admin.site.register(Author)
          class BookConfig(admin.ModelAdmin):
               pass
          admin.site.register(Book,BookConfig)
          
          
          源码:
              admin.py---sites.py---->
              class AdminSite(object):
              
                  def __init__(self):
                        self._registry = {}
              
                  def register(self,model,admin_class=None):
                       if not admin_class:
                            admin_class = ModelAdmin
                            
                            
                       self._registry[model] = admin_class(model, self)        
              
              
              site = AdminSite()

转载于:https://www.cnblogs.com/yb635238477/p/9545095.html

django中的admin组件相关推荐

  1. django中的admin组件之自定义组件的增删改查的完善

    昨天我们将自定义列放在类我们自定义的Bookconfig配置类内,但是这样就写死了,因为当我们访问publish表的时候应该也有这样的自定义列,所以我们应该将我们的自定义列放在默认的配置表里面.应该怎 ...

  2. Django中的admin

    1.基本知识 在用Django框架写了一个网站之后,我们添加数据大概有两种方式: 1.在连接的数据库中添加数据 2.登录admin,进入后台添加数据 创建一个Django项目后,我们在url.py中会 ...

  3. django框架之form组件

    内容回顾: 1. 内容回顾     1. 复习JSON         1. JSON是什么?             一种数据格式,和语言无关的数据格式.         2. Python里面转换 ...

  4. Django admin组件源码流程

    admin 组件 Django 自带的用户后台组件 用于用户便携的操作 admin 组件核心 启动 注册 设计url 启动核心代码 每个app 通过 apps.py 扫描 admin.py 文件 并执 ...

  5. django的admin组件使用详解

    一.admin组件介绍 admin作为django的超级用户,权限包括注册目录列表,注册用户权限,注册需要维护的数据库信息等. 二.admin组件的使用 1. 启动项目 访问localhost:800 ...

  6. 1月24日学习内容整理:Django的admin组件源码分析及流程

    一.单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用 ...

  7. Django中model新建数据表操作后admin页面不更新问题

    Django中model新建数据表操作后admin页面不更新问题 这种情况一般是没有在admin.py文件中进行模型的注册所导致的,打开应用文件夹下的admin.py,然后添加代码: from .mo ...

  8. mysql 中的neq_mysql中neq使用Python的Django框架中的压缩组件Django Compressor_MySQL

    为了加快网站的加载速度,我们通常要多js和css进行压缩处理.这些js和css的压缩工作如果都手动处理,费时费力. <mysql中neq使用Python的Django框架中的压缩组件Django ...

  9. django admin组件

    admin实例 from django.contrib import admin from app01 import models from django.utils.safestring impor ...

最新文章

  1. 西南科技大学智能车竞赛 线上比赛
  2. 移动端、PC端网站优化需齐头并进
  3. 洞悉linux下的Netfilteriptables
  4. java多线程优先级的方法_Java多线程以及线程优先级
  5. leetcode434. 字符串中的单词数
  6. oreo另一个意思_记一次有意思的统计(部分大宗商品价格指数相关性统计)
  7. python处理一些乱码的中文文本时decode('utf-8')报错的处理
  8. apache-hive-3.1.0-bin.tar.gz 下载
  9. 解决Vue3的undefined问题
  10. 千图网免费下载工具(windows版)
  11. 一首能记住网线水晶头接法诗
  12. 计算机基础2,计算机基础总结2
  13. HBase NoSQL数据库详解
  14. 方波的产生——运算放大器LM324产生方波
  15. APP加密,ios代码混淆工具,虚拟化技术 适用于移动应用程序的虚拟化加密软件
  16. gpu-z怎么用,显卡怎么看体质
  17. [bzoj5507] [洛谷P5305] [gzoi2019]旧词
  18. Iconfont-阿里巴巴矢量图标库 用 github账户无法登录
  19. 修改windows启动画面:Logonui.exe
  20. Unity3d HoloLens的MRTK TextMeshProUGUI中文显示框框乱码需自制字体Font

热门文章

  1. 在jsp文件中通过超链接访问servlet_Eclipse中创建Servlet
  2. 一维二维_更高效的一维、二维材料过渡态搜索
  3. 字符串倒着输出java_Java 输出反转字符串
  4. py脚本:linux系统下定时清理文件
  5. c++实现简单线程池代码
  6. leetcode 1. 两数之和 思考分析
  7. 智能车复工日记【7】:关于会车的图像问题
  8. db,dbms,dba_DBMS中的数据库管理员(DBA)
  9. web安全----XSS漏洞之基本原理
  10. Hibernate中把Session和线程绑定的配置