在文章stark组件前戏中已经提到过,django的注册功能是通过AdminSite的单例进行组册的,所以在这里也可以进行单例模式。

class AdminSite(object):

    def __init__(self):
self._registry=[]
self.app_name='stark'
self.namespace='stark' def register(self,model_class,stark_class=None,prev=None): if not stark_class:
stark_class=BaseStark self._registry.append(ModelStarkMapping(model_class,stark_class(model_class,self,prev),prev))
#self._registry.append({'model':model_class,'stark_class':stark_class(model_class,self,prev),prev})
# for k,v in self._registry.items():
# print(k,v)0
"""
    之前
_registry={
'UserInfo':BaseStark(UserInfo,site) 封装UserInfo类和site
'Role':RoleStark(Role,site) 封装 Role类和site
}
""" def get_urls(self):
urlpatterns=[] for item in self._registry: #循环得到的是每一个ModelStarkMapping对象
app_label=item.model_class._meta.app_label
model_name=item.model_class._meta.model_name
if item.prev:
temp = path('%s/%s/%s/' % (app_label, model_name,item.prev), (item.stark_class.urls, None, None))
else:
temp = path('%s/%s/' % (app_label, model_name,), (item.stark_class.urls, None, None))
urlpatterns.append(temp)
return urlpatterns @property
def urls(self):
return self.get_urls(),self.app_name,self.namespace

可以看到之前_registry是一个字典,现在变成了一个列表,为什么要这样做呢?

(1)这是因为如果是字典的话,一个model只能注册一次,现在是model可以注册多次,只需要将model对应的类按照需要表换,这样在一个页面上来实现一个model不同的数据展示。

(2)pre前缀的功能是为了将不同model注册的url加以区别,如下所示:

site.register(models.Customer,PersonalCustomerStark,'per')
site.register(models.Customer,CustomerStark)

另外将一个个字典的内容封存为一个对象,这样取值方便,当然,字典也是没问题的。

class ModelStarkMapping(object):

    def __init__(self,model_class,stark_class,prev):
self.model_class=model_class
self.stark_class=stark_class
self.prev=prev

这就是注册功能的实现过程,接下来就是路由系统的构建。

可以看到上述在返回urlpatterns列表时,第二个元素是三个参数组成的元组,按理说应该是include()进行二级路由分发才对呀,其实这是include()方法的本质,在include()方法中返回的就是这么三个参数的元组。

def include(arg, namespace=None):
app_name = None
if isinstance(arg, tuple):
# Callable returning a namespace hint.
try:
urlconf_module, app_name = arg
except ValueError:
if namespace:
raise ImproperlyConfigured(
'Cannot override the namespace for a dynamic module that '
'provides a namespace.'
)
raise ImproperlyConfigured(
'Passing a %d-tuple to include() is not supported. Pass a '
'2-tuple containing the list of patterns and app_name, and '
'provide the namespace argument to include() instead.' % len(arg)
)
else:
# No namespace hint - use manually provided namespace.
urlconf_module = arg if isinstance(urlconf_module, str):
urlconf_module = import_module(urlconf_module)
patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)
app_name = getattr(urlconf_module, 'app_name', app_name)
if namespace and not app_name:
raise ImproperlyConfigured(
'Specifying a namespace in include() without providing an app_name '
'is not supported. Set the app_name attribute in the included '
'module, or pass a 2-tuple containing the list of patterns and '
'app_name instead.',
)
namespace = namespace or app_name
# Make sure the patterns can be iterated through (without this, some
# testcases will break).
if isinstance(patterns, (list, tuple)):
for url_pattern in patterns:
pattern = getattr(url_pattern, 'pattern', None)
if isinstance(pattern, LocalePrefixPattern):
raise ImproperlyConfigured(
'Using i18n_patterns in an included URLconf is not allowed.'
)
return (urlconf_module, app_name, namespace)

include()

然后可以看看二级路由,在BaseStark这个基类中定义了二级路由。

...   
def get_urls(self):
urlpatterns = [
re_path('list/$', self.wrapper(self.changelist_view), name=self.get_list_url_name ),
re_path('add/$', self.wrapper(self.add_view), name=self.get_add_url_name),
re_path('(?P<pk>\d+)/change/$', self.wrapper(self.change_view), name=self.get_edit_url_name),
re_path('(?P<pk>\d+)/del/$', self.wrapper(self.del_view), name=self.get_del_url_name), ]
extra_urls = self.extra_urls() if extra_urls:
urlpatterns.extend(extra_urls) return urlpatterns def extra_urls(self): # 用于扩展url 返回的是一个列表,一次性扩展多个值
pass @property
def urls(self): return self.get_urls()
...

这样就完成了注册与路由构建。

stark组件之注册与路由系统(三)的更多相关文章

  1. stark组件之注册【模仿Django的admin】

    一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...

  2. stark组件之路由分发【模仿Django的admin】

    一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...

  3. CRM项目之stark组件

    . stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...

  4. Stark组件 (一)

    Stark组件构建 1.启动所有app下的stark.py文件,的配置实现步骤 1.创建一个Django项目crm,并创建  app1 ,app2, stark 三个app 2.在crm 项目的set ...

  5. django中admin路由系统工作原理

    一.如图所示 from django.contrib import admin from . import models class zhangsan(admin.ModelAdmin): list_ ...

  6. python 全栈开发,Day112(内容回顾,单例模式,路由系统,stark组件)

    一.内容回顾 类可否作为字典的key 初级 举例: class Foo(object): pass _registry = { Foo:123 } print(_registry) 执行输出: {&l ...

  7. 插件占坑,四大组件动态注册前奏(三) 系统BroadCast的注册发送流程

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52204143 前言:为什么要了解系统Activity,Service,BroadCas ...

  8. Flask 基础组件(三):路由系统

    1. 常见路由 @app.route('/user/<username>') @app.route('/post/<int:post_id>') @app.route('/po ...

  9. CRM系统 - 总结 (二) stark组件

    介绍: stark组件,是一个帮助开发者快速实现数据库表的增删改查+的组件.目标: 10s 中完成一张表的增删改查. 前戏: django项目启动时,自定义执行某个py文件. django启动时,且在 ...

随机推荐

  1. Spring Boot:关于“No converter found for return value of type: class xxx”的解决方法

    首先在对应的controller中的@RestController中返回json对象的操作 public class HelloController { @RequestMapping("/ ...

  2. ACM复习专项

    资料整理 ACM训练营 邝斌的ACM模板 牛客网哈理工ACM教学视频 视频网盘资料(密码:kntr) 1. 训练阶段 第一阶段:练习经典常用算法 (本周任务) 1. 最短路(Floyd.Dijstra ...

  3. 配置Ubuntu16.04第03步:安装搜狗输入法

    1.进入搜狗官网:https://pinyin.sogou.com/linux/ ,下载搜狗输入法安装包 2.使用dpkg命令安装Deb包: sudo dpkg -i sogoupinyin_2.0. ...

  4. Proactive Patching Overview

    1.Proactive Patching Overview Between Patch Set releases, Oracle's proactive patching program provid ...

  5. JDK11源码分析之集合类(一)----HashMap

    一,首先需要拉取JDK11源码: 方便起见我给出芋道源码作者已经拉取好的openJDK11的GitHub地址只需要fork一下克隆到本地导入IDEA中就可以对源码分析了: https://github ...

  6. Elasticsearch--集群管理_别名&插件&更新API

    目录 使用索引别名 别名 创建别名 修改别名 合并命令 获取所有别名 移除别名 别名中过滤 别名和路由 Elasticsearch插件 基础知识 安装插件 移除插件 更新设置API 使用索引别名 通过 ...

  7. flex弹性布局操练1

    实现弹性布局之前常用浮动,相对定位和绝对定位等,但是现在好了,随着flex的兴起,方便了很多,而且也符合未来响应式布局的方向. 理论的东西可参考css3手册,这里专注实操. 一:单个元素 <di ...

  8. php(一)

    PHP (Hypertext preprocessor 超文本预处理器) 1.环境工具 Xampp等工具 2.apache配置 默认的Apache路径是  c:/xampp/apache 文件夹 可以 ...

  9. spring 整合struts

    1.例子:未被spring整合 struts.xml 的配置文件 <constant name="struts.enable.DynamicMethodInvocation" ...

  10. windows下管理ubuntu服务器以及切换root身份

    远程连接Linux云服务器-命令行模式 1.远程连接工具.目前Linux远程连接工具有很多种,您可以选择顺手的工具使用.下面使用的是名为Putty(putty.rar)的Linux远程连接工具.该工具 ...