zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    子集生成——增量构造法+位向量法+二进制法
    记忆化搜索
    欧拉回路和欧拉通路
    拓扑排序(基于dfs+基于队列)
    HDU 3839 Ancient Messages(DFS)
    【gulp】前端自动化工具---gulp的使用(一)------【巷子】
    【面向对象】用大白话扯扯那"神奇"的面向对象之方法继承(五)------【巷子】
    【面向对象】----【prototype&&__proto__&&实例化对象三者之间的关系】(四)-----【巷子】
    【面向对象】用大白话扯扯那"神奇"的面向对象之属性继承(三)------【巷子】
    【面向对象】用大白话扯扯那"神奇"的面向对象编程思维(二)------【巷子】
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/12864057.html
Copyright © 2011-2022 走看看