admin流程之启动

单例模式

单例:只允许一个类实例化出一个对象

使用 new

为了使类只能出现一个实例,我们可以使用 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  

egon=Animal()
alex=Animal()
wupeiqi=Animal()

print(id(egon))
print(id(alex))
print(id(wupeiqi))
#三者完全相同

在上面的代码中,我们将类的实例和一个类变量 _instance 关联起来,
如果 cls._instance 为 None 则创建实例,否则直接返回 cls._instance。

使用模块

其实,Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。
因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
如果我们真的想要一个单例类,可以考虑这样做:
#mysingleton.py

class My_Singleton(object):
    def foo(self):
        pass

my_singleton = My_Singleton()

将上面的代码保存在文件 mysingleton.py 中,然后这样使用:

from mysingleton import my_singleton

my_singleton.foo()

admin流程之注册

admin.site : 单例对象

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

 #model就是表对象(Book),admin_class就是表的配置类(BookConfig)   
    def register(self, model, admin_class=None, **options):
            if not admin_class:
                #配置类
                    admin_class = ModelAdmin

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

site=AdminSite()

admin.site.register(Book,BookConfig)
admin.site.register(Book)    #  site._registry:{Book:ModelAdmin(Book)}
admin.site.register(Publish) #  site._registry:{Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}

#site._registry:{模型类:该模型类的配置类对象,........}

知识点:url分发扩展

url()方法的扩展应用

from django.shortcuts import HttpResponse
    url(r'^index/', index), # 一旦匹配成功, index(request)

        urlpatterns = [
            url(r'^admin/', admin.site.urls),

            url(r'^yuan/', ([
                    url(r'^test01/', ([
                                url(r'^test1_1/', test01),
                                url(r'^test1_2/', test01),
                                    ],None,None)),
                    url(r'^test02/', test02),
                    url(r'^test03/', test03),
                            ],None,None)),
        ] 

格式,元祖里面是一个列表+None+None

admin流程之设计url

admin中:

from app01 import models

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

urls.py中:

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import render, HttpResponse, redirect

def list_view(request):
    return HttpResponse("list_view")

def change(request, id):
    return HttpResponse("change")

def delete(request, id):
    return HttpResponse("delete")

def add(request):
    return HttpResponse("add")

def get_urls2():
    temp = [
        url("^add/$", add),
        url("^$", list_view),
        url("^(\d+)/change/$", change),
        url("^(\d+)/delete/$", delete)
    ]

    return temp

def get_urls():
    temp = []

    print("_registry==>", admin.site._registry.items())
    #{Book:ModelAdmin(Book),....}
    #(<class 'app01.models.Book'>, <django.contrib.admin.options.ModelAdmin object at 0x00000234441F99B0>)
    #Django启动会先加载settings,因此_registry中有值
    for model, model_class_obj in admin.site._registry.items():

        app_name = model._meta.app_label
        #model._meta.app_label可以获取当前model所在app的名字
        model_name = model._meta.model_name
        #model._meta.model_name可以获得当前model的名称字符串

        #用stark+app的名字+模型表的名字
        #举例:http://127.0.0.1:8000/stark/app01/book/02/change/
        temp.append(url(r"%s/%s/" % (app_name, model_name), (get_urls2(), None, None)))

    return temp

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # [
    #    url(r'^test01/', test01),
    #    url(r'^test02/', test02),
    #                 ]
    url(r"^stark",(get_urls(),None,None))
]

最终url示例:

^stark auth/group/
^stark auth/user/
^stark app01/book/ ^add/$
^stark app01/book/ ^$
^stark app01/book/ ^(\d+)/change/$
^stark app01/book/ ^(\d+)/delete/$
^stark app01/publish/
^stark app01/author/