admin组件

详见

django-admin的源码流程

一、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

 

 

posted @ 2020-05-10 16:52  zh_小猿  阅读(118)  评论(0编辑  收藏  举报