在文章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. 洛谷P4550 收集邮票(概率期望)

    传送门 神仙题啊……这思路到底是怎么来的…… ps:本题是第$k$次买邮票需要$k$元,而不是买的邮票标号为$k$时花费$k$元 我们设$g[i]$表示现在有$i$张,要买到$n$张的期望张数,设$P ...

  2. 安装MySQL需要注意的事项

    一.安装MySQL之后,怎样启动MySQL,以及登录.查看数据库操作? 用管理员身份运行cmd或power shell 二.当然有可能会出现不能在cmd或power shell中登录数据库账户 造成这 ...

  3. JavaScript 入门案例

    四.  JavaScript 入门案例 在看本节之前,笔者建议您先看 JavaScript 基础篇  https://www.cnblogs.com/IT-LFP/p/10945884.html 1. ...

  4. 记一次线上环境的内存溢出(java.lang.OutOfMemoryError)

    事故背景 今天客户说风控项目有个别用户查询不到数据不是报错就是一直卡在那里,我就去那个接口看了下. 一看项目日志今天的都几个g了,平常也就几百兆吧,很明显出了问题. 请求接口后使用命令tail -f ...

  5. Step 4: Install and Configure Databases

    https://www.cloudera.com/documentation/enterprise/latest/topics/cm_ig_installing_configuring_dbs.htm ...

  6. [Usaco2011 Feb]Generic Cow Protests

    Description Farmer John's N (1 <= N <= 100,000) cows are lined up in a row and numbered 1..N. ...

  7. vscode增加sftp扩展

    下载 sftp-sync 扩展插件 填写配置 快捷键 ctrl+shift+P 打开指令窗口,输入sftp:config,回车,就会在当前工作工程的.vscode文件夹下生成一个sftp.json文件 ...

  8. Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库上下文

    导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件 下一篇:Farseer.net轻量级ORM开源 ...

  9. vue2.0 组件化

    简单理解其实组件就是制作自定义的标签,这些标签在HTML中是没有的. 组件注册的是一个标签,而指令注册的是已有标签里的一个属性.在实际开发中我们还是用组件比较多,指令用的比较少. <!DOCTY ...

  10. 【译】x86程序员手册39-10.3切换到保护模式

    10.3 Switching to Protected Mode  切换到保护模式 Setting the PE bit of the MSW in CR0 causes the 80386 to b ...