一、admin组件简单使用
models.py
from django.db import models # Create your models here. 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) def __str__(self): return self.name 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() def __str__(self): return self.name 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',) def __str__(self): return self.title
admin.py文件中,注册表
from django.contrib import admin # Register your models here. from .models import * admin.site.register(Book) admin.site.register(Publish) admin.site.register(Author) admin.site.register(AuthorDetail)
现在定义自己的样式供book表展示
admin.py
from django.utils.safestring import mark_safe #定义一个自己的样式供book表展示 class BookConfig(admin.ModelAdmin): #除了能放表的字段之外,还能定义一个函数,加入其它字段,如下面的delete def deletes(self): return mark_safe("<a href=''>删除</a>") # 1 在展示页面前把展示对象改为展示哪些字段(不能是manytomany字段) list_display = ["title","price","publishDate",'publish',deletes] # 2 设置点击price可以进入编辑界面 list_display_links = ["price"] # 3 页面右侧可以根据下面字段进行快速筛选。 list_filter=["price","title","authors","publish"] # 4 定制可以编辑的列 list_editable=["title",] # 5 定制模糊搜索的功能,可以根据title和price的内容进行模糊搜索 search_fields=["title","price"] # 6 定制action操作,下面定制批量处理的方法 def patch_init(self,request,queryset): #queryset就是我们选中的数据,这里把我们选中的数据全部更新为100 queryset.update(price=100) #为我们自定义的函数加上中文描述 patch_init.short_description = "批量初始化" #最后把函数放入actions列表中 actions = [patch_init,] #定制HTML模板 #change_list_template="list.html" # 控制显示添加页面的哪些字段, fields = ('title',) #在添加页面只显示title字段,可把那些为空的字段隐藏起来用户不必填写
然后设置:
admin.site.register(Book,BookConfig) #Book使用我们自己写的类
经过以上步骤book页面展示如下:
二、admin组件执行流程
<1> 循环加载执行所有已经注册的app中的admin.py文件
def autodiscover(): autodiscover_modules('admin', register_to=site)
<2> 执行代码
#admin.py
class BookAdmin(admin.ModelAdmin): list_display = ("title",'publishDate', 'price')
admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
<3> admin.site
这里应用的是一个单例模式,对于AdminSite类的一个单例模式,执行的每一个app中的每一个admin.site都是一个对象
<4> 执行register方法
admin.site.register(Book, BookAdmin)
admin.site.register(Publish)
class AdminSite(object): def __init__(self, name='admin'): self._registry = {} # model_class class -> admin_class instance def register(self, model_or_iterable, admin_class=None, **options): if not admin_class: admin_class = ModelAdmin # Instantiate the admin class to save in the registry self._registry[model] = admin_class(model, self)
admin.site.register(Book)就相当于执行上面的代码,执行完之后上面的self._registry里面就多了一个键值{Book:ModelAdmin(Book)},此时:
admin.site._registry={Book:ModelAdmin(Book)}
admin.site.register(Publish)执行完之后self._registry里面就就又增加一个键值{Publish:ModelAdmin(Publish)},此时:
admin.site._registry={Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}
如果定义自己的类:
class Authoconfig(admin.ModelAdmin): pass
admin.site.registry(Author,Authoconfig)执行完之后:
admin.site._registry={Book:ModelAdmin(Book),Publish:ModelAdmin(Publish),Author:Authoconfig(Author)}
思考:在每一个app的admin .py中加上
print(admin.site._registry) # 执行结果?
到这里,注册结束!
<5> admin的URL配置
urlpatterns = [ url(r'^admin/', admin.site.urls), ]
class AdminSite(object): def get_urls(self): from django.conf.urls import url, include urlpatterns = [] # 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) return urlpatterns @property def urls(self): return self.get_urls(), 'admin', self.name
单例模式的几个例子:
mysingleton.py
class My_Singleton(object): def foo(self): print("foo.....") my_singleton = My_Singleton()
func.py
from mysingleton import my_singleton #不会再次执行模块代码,直接从,pyc中拿已近实例化的对象 def bar(): print(id(my_singleton)) # 2238305368832
main.py
class Person(object): def __init__(self,name,age): self.name=name self.age=age alex=Person("alex",33) egon=Person("egon",32) # 单例模式 # 单例模式方式1 :__new__ class Singleton(object): _instance = None def __new__(cls, *args, **kw): if not cls._instance: cls._instance = super(Singleton, cls).__new__(cls, *args, **kw) return cls._instance class MyClass(Singleton): a = 1 mc1=MyClass() mc2=MyClass() mc3=MyClass() print(id(mc1)) #1888834230984 print(id(mc2)) #1888834230984 print(id(mc3)) #1888834230984 # 单例模式方式2 :模块方式 #python在加载模块时只加载一次 #第一次导入模块时,会生成 .pyc 文件 from mysingleton import my_singleton,My_Singleton my_singleton.foo() #foo..... print(id(my_singleton)) # 1888834372048 # 思考1 # 第二次导入模块时就会直接加载 .pyc 文件,而不会再次执行模块代码 # 因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。 from mysingleton import my_singleton as my_singleton_new # print(id(my_singleton_new)) # 1888834372048 print(id(my_singleton)) # 1888834372048 # 思考2 import func func.bar() # 1888834372048 # 思考3 from mysingleton import my_singleton,My_Singleton ms1=My_Singleton() from mysingleton import my_singleton,My_Singleton ms2=My_Singleton() print(id(ms1)) #1888834231040 print(id(ms2)) #1888834231096