• Django-admin源码流程


    from django.db import models
    
    class Role(models.Model):
        caption = models.CharField(max_length=32)
    
        class Meta:
            verbose_name_plural = "角色表"
    
        def __str__(self):
            return self.caption
    class UserType(models.Model):
        title = models.CharField(max_length=32)
        roles = models.ManyToManyField(to=Role)
    
        def __str__(self):
            return self.title
    class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        email = models.EmailField(max_length=32)
        ut = models.ForeignKey(to=UserType,null=True,blank=True)
    app01.models
    from django.db import models
    
    
    class Article(models.Model):
        title = models.CharField(max_length=32)
    app02.models

    admin源码流程

    - 文件加载
    第一次导入后,再次导入时不再重新加载

    a. 运行程序,找到每一个app中的 admin.py 文件,并加载

      

    - app01.admin.py

    from django.contrib import admin
    from app01 import models
    """
    
    _registry = {
        models.Role: ModelAdmin(models.Role,admin.site),
        models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
        models.UserType: ModelAdmin(models.UserType,admin.site)
    }
    
    """
    admin.site.register(models.Role)
    admin.site.register(models.UserInfo)
    admin.site.register(models.UserType)


    - 创建admin.site中的对象

    class AdminSite中
    site = AdminSite()
        def __init__(self, name='admin'):
            self._registry = {}  # model_class class -> admin_class instance
            self.name = name
            self._actions = {'delete_selected': actions.delete_selected}
            self._global_actions = self._actions.copy()
            all_sites.add(self)

    - 执行对象的 register方法,目的:讲注册类添加到 _registry中

    #model_or_iterable 就是我们操作的对象比如models.userinfo
    #admin_class 一般是指ModelAdmin
     def register(self, model_or_iterable, admin_class=None, **options):
            """
            Registers the given model(s) with the given admin class.
    
            The model(s) should be Model classes, not instances.
    
            If an admin class isn't given, it will use ModelAdmin (the default
            admin options). If keyword arguments are given -- e.g., list_display --
            they'll be applied as options to the admin class.
    
            If a model is already registered, this will raise AlreadyRegistered.
    
            If a model is abstract, this will raise ImproperlyConfigured.
            """
            if not admin_class:
                admin_class = ModelAdmin
    
            if isinstance(model_or_iterable, ModelBase):
                model_or_iterable = [model_or_iterable]
            for model in model_or_iterable:
                if model._meta.abstract:
                    raise ImproperlyConfigured(
                        'The model %s is abstract, so it cannot be registered with admin.' % model.__name__
                    )
    
                if model in self._registry:
                    raise AlreadyRegistered('The model %s is already registered' % model.__name__)
    
                # Ignore the registration if the model has been
                # swapped out.
                if not model._meta.swapped:
                    # If we got **options then dynamically construct a subclass of
                    # admin_class with those **options.
                    if options:
                        # For reasons I don't quite understand, without a __module__
                        # the created class appears to "live" in the wrong place,
                        # which causes issues later on.
                        options['__module__'] = __name__
                        admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
    
                    # Instantiate the admin class to save in the registry
                    self._registry[model] = admin_class(model, self)

    _registry 中现在存的值
        _registry = {
                            models.Role: ModelAdmin(models.Role,admin.site),
                            models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
                            models.UserType: ModelAdmin(models.UserType,admin.site)
                        }

    - app02.admin.py
    - 用app01.admin中创建那个admin.site对象
    - 执行对象的 register方法,目的:讲注册类添加到 _registry中

     流程和app01一样,这里不再赘述

    _registry = {
                            models.Role: ModelAdmin(models.Role,admin.site),
                            models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
                            models.UserType: ModelAdmin(models.UserType,admin.site)
                            models.Article: ModelAdmin(models.Article,admin.site)
                        }
    admin.site是一个对象(单例模式创建),其中封装了: 
                    _registry = {
                        models.Role: ModelAdmin(models.Role,admin.site),
                        models.UserInfo: ModelAdmin(models.UserInfo,admin.site)
                        models.UserType: ModelAdmin(models.UserType,admin.site)
                        models.Article: ModelAdmin(models.Article,admin.site)
                    }

    b. urls.py
    再次调用 admin.site 对象的 urls属性:

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

    class AdminSite中

     @property
        def urls(self):
            return self.get_urls(), 'admin', self.name #返回的是一个元祖,并且第一个元素是一个列表
        def get_urls(self):
            from django.conf.urls import url, include
            # Since this module gets imported in the application's root package,
            # it cannot import models from other applications at the module level,
            # and django.contrib.contenttypes.views imports ContentType.
            from django.contrib.contenttypes import views as contenttype_views
    
            def wrap(view, cacheable=False):
                def wrapper(*args, **kwargs):
                    return self.admin_view(view, cacheable)(*args, **kwargs)
                wrapper.admin_site = self
                return update_wrapper(wrapper, view)
    
            # Admin-site-wide views.
            urlpatterns = [
                url(r'^$', wrap(self.index), name='index'),
                url(r'^login/$', self.login, name='login'),
                url(r'^logout/$', wrap(self.logout), name='logout'),
                url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
                url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
                    name='password_change_done'),
                url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
                url(r'^r/(?P<content_type_id>d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
                    name='view_on_site'),
            ]
    
            # Add in each model's views, and create a list of valid URLS for the
            # app_index
    #
    model._meta.app_label 得到app的名称
            # model._meta.model_name 得到当前类的名称
            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)
    
            # If there were ModelAdmins registered, we should have a list of app
            # labels for which we need to allow access to the app_index view,
            if valid_app_labels:
                regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$'
                urlpatterns += [
                    url(regex, wrap(self.app_index), name='app_list'),
                ]
            return urlpatterns

    modelAdmin中

      @property
        def urls(self):
            return self.get_urls()
     def get_urls(self):
            from django.conf.urls import url
    
            def wrap(view):
                def wrapper(*args, **kwargs):
                    return self.admin_site.admin_view(view)(*args, **kwargs)
                wrapper.model_admin = self
                return update_wrapper(wrapper, view)
    
            info = self.model._meta.app_label, self.model._meta.model_name
    
            urlpatterns = [
                url(r'^$', wrap(self.changelist_view), name='%s_%s_changelist' % info),
                url(r'^add/$', wrap(self.add_view), name='%s_%s_add' % info),
                url(r'^(.+)/history/$', wrap(self.history_view), name='%s_%s_history' % info),
                url(r'^(.+)/delete/$', wrap(self.delete_view), name='%s_%s_delete' % info),
                url(r'^(.+)/change/$', wrap(self.change_view), name='%s_%s_change' % info),
                # For backwards compatibility (was the change url before 1.9)
                url(r'^(.+)/$', wrap(RedirectView.as_view(
                    pattern_name='%s:%s_%s_change' % ((self.admin_site.name,) + info)
                ))),
            ]
            return urlpatterns

    基于admin源码简单示例

    """s6day102 URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from django.shortcuts import HttpResponse
    def changelist_view(request):
        return HttpResponse('列表页面')
    
    def add_view(request):
        return HttpResponse('添加页面')
    
    
    def delete_view(request,nid):
        return HttpResponse('删除页面')
    
    def change_view(request,nid):
        return HttpResponse('修改页面')
    
    url_list = []
    for model_class,v in admin.site._registry.items():
        # 循环执行每一个类
    
        # 当前类名小写
        cls_name = model_class._meta.model_name
        # 当前类所在的app名称
        app_name = model_class._meta.app_label
    
        list_url = url(r'^{0}/{1}/$'.format(app_name,cls_name), changelist_view)
        url_list.append(list_url)
    
        add_url = url(r'^{0}/{1}/add/$'.format(app_name, cls_name), add_view)
        url_list.append(add_url)
    
        del_url = url(r'^{0}/{1}/(d+)/del/$'.format(app_name, cls_name), delete_view)
        url_list.append(del_url)
    
        change_url = url(r'^{0}/{1}/(d+)/change/$'.format(app_name, cls_name), change_view)
        url_list.append(change_url)
    
    
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # url(r'^shensong/', ([
        #                         url(r'^login/$',login, name='login'),
        #                     ],None,None) ),
        url(r'^wenfei/', (url_list,None,None,) ),
    ]
    示例一 简单
    """s6day102 URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url,include
    from django.contrib import admin
    from django.shortcuts import HttpResponse
    def changelist_view(request):
        return HttpResponse('列表页面')
    
    def add_view(request):
        return HttpResponse('添加页面')
    
    
    def delete_view(request,nid):
        return HttpResponse('删除页面')
    
    def change_view(request,nid):
        return HttpResponse('修改页面')
    
    def get_urls():
        temp = [
            url(r'^$'.format(app_name, cls_name), changelist_view),
            url(r'^add/$'.format(app_name, cls_name), add_view),
            url(r'^del/$'.format(app_name, cls_name), delete_view),
            url(r'^change/$'.format(app_name, cls_name), change_view)
        ]
        return temp
    
    
    url_list = []
    for model_class,v in admin.site._registry.items():
        # 循环执行每一个类
    
        # 当前类名小写
        cls_name = model_class._meta.model_name
        # 当前类所在的app名称
        app_name = model_class._meta.app_label
    
        # all_url = url(r'^{0}/{1}/'.format(app_name,cls_name), (get_urls(),None,None,) )
        all_url = url(r'^{0}/{1}/'.format(app_name,cls_name), include(get_urls()) )
    
        url_list.append(all_url)
    
    
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^shensong/', ([
                                url(r'^app01/userinfo/$',([
                                                            url(r'^$',changelist_view, name='login'),
                                                            url(r'^add/$',add_view, name='login'),
                                                            url(r'^(d+)/del/$',delete_view, name='login'),
                                                            url(r'^(d+)/change/$',change_view, name='login'),
                                                          ],None,None)),
                                url(r'^app01/usertype/$',([
                                                            url(r'^$',changelist_view, name='login'),
                                                            url(r'^add/$',add_view, name='login'),
                                                            url(r'^(d+)/del/$',delete_view, name='login'),
                                                            url(r'^(d+)/change/$',change_view, name='login'),
                                                          ],None,None)),
                                url(r'^app01/role/$',([
                                                            url(r'^$',changelist_view, name='login'),
                                                            url(r'^add/$',add_view, name='login'),
                                                            url(r'^(d+)/del/$',delete_view, name='login'),
                                                            url(r'^(d+)/change/$',change_view, name='login'),
                                                          ],None,None)),
                                url(r'^app02/article/$', ([
                                                           url(r'^$', changelist_view, name='login'),
                                                           url(r'^add/$', add_view, name='login'),
                                                           url(r'^(d+)/del/$', delete_view, name='login'),
                                                           url(r'^(d+)/change/$', change_view, name='login'),
                                                       ], None, None)),
                            ],None,None) ),
        url(r'^wenfei/', (url_list,None,None,) ),
    
    ]
    示例二


  • 相关阅读:
    万网免费主机wordpress快速建站教程-域名绑定及备案
    java小算法—大衍数列
    Core Data使用之一(Swift): 保存
    Swift 添加到TableView实现动画效果
    Swift 动态创建提示框
    Swift分割字符串
    Swift去除两边的特定字符(空格或其它)
    windows 属性
    String 输出{}
    c# 正则表达式的用户
  • 原文地址:https://www.cnblogs.com/ctztake/p/8039973.html
Copyright © 2020-2023  润新知