stark组件之注册与路由系统(三)
在文章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组件之注册与路由系统(三)的更多相关文章
- stark组件之注册【模仿Django的admin】
一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...
- stark组件之路由分发【模仿Django的admin】
一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...
- CRM项目之stark组件
. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...
- Stark组件 (一)
Stark组件构建 1.启动所有app下的stark.py文件,的配置实现步骤 1.创建一个Django项目crm,并创建 app1 ,app2, stark 三个app 2.在crm 项目的set ...
- django中admin路由系统工作原理
一.如图所示 from django.contrib import admin from . import models class zhangsan(admin.ModelAdmin): list_ ...
- python 全栈开发,Day112(内容回顾,单例模式,路由系统,stark组件)
一.内容回顾 类可否作为字典的key 初级 举例: class Foo(object): pass _registry = { Foo:123 } print(_registry) 执行输出: {&l ...
- 插件占坑,四大组件动态注册前奏(三) 系统BroadCast的注册发送流程
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52204143 前言:为什么要了解系统Activity,Service,BroadCas ...
- Flask 基础组件(三):路由系统
1. 常见路由 @app.route('/user/<username>') @app.route('/post/<int:post_id>') @app.route('/po ...
- CRM系统 - 总结 (二) stark组件
介绍: stark组件,是一个帮助开发者快速实现数据库表的增删改查+的组件.目标: 10s 中完成一张表的增删改查. 前戏: django项目启动时,自定义执行某个py文件. django启动时,且在 ...
随机推荐
- SpringBoot项目docker化
前言 有很多种方案构建Docker镜像,包括Dockerfile构建.maven插件构建,这里我使用了最简单的Dockerfile构建的. 一.安装Docker 我的虚拟机系统是CentOS7,需要是 ...
- CAD中的文本编排操作
AutoCAD中导入超文本实现方法 除了AutoCAD内含的文本输入命令外,向AutoCAD中输入多行文本即超文本的方法还有:通过Windows提供的剪贴板,利用AutoCAD提供的多行文本命 ...
- 数据结构 - 顺序队列的实行(C语言)
数据结构-顺序队列的实现 1 顺序队列的定义 线性表有顺序存储和链式存储,队列作为一种特殊的线性表,也同样存在这两种存储方式.我们先来看队列的顺序存储结构. 队列的顺序储存结构:用数组存储队列,为了避 ...
- Android 线程池系列教程(1)目录
Sending Operations to Multiple Threads 1.Dependencies and prerequisites Android 3.0 (API Level 11) o ...
- 框架系列~OwinSelfHost自宿主的使用
在进入mvc5之后,OWIN变更很主推,很热,关于OWIN的文章也就出来了,下面阅读了dudu和一些园友的文章,自己也做了一个SelfHost的程序,测试了一下,感觉还是比较有Core的风格,可能也是 ...
- Sort排序浅聊
集合是什么?笔者简易描述:数组是不可变的,所以我们使用集合来代替. using.System.Collections; 非泛型集合 using.System.Collections.Gernerc;泛 ...
- 461在全志r16平台tinav3.0系统下使用地磁计QMC5883L
461在全志r16平台tinav3.0系统下使用地磁计QMC5883L 2018/9/7 14:08 版本:V1.0 开发板:SC3817R SDK:tina v3.0 (基本确认全志tina v3. ...
- axis2与eclipse的整合:开始一个简单的axis2 的demo
1.下载axis2,现在axis2最新版本是axis2-1.6.2,下载地址:http://axis.apache.org/axis2/java/core/download.cgi 2.下载好的zip ...
- [备忘]Notification的实用
Intent resultIntent = null; if (!TextUtils.isEmpty(tid)){ resultIntent = new Intent("com.shijie ...
- taskctl的后台字符界面登录不了解决办法
今天在使用taskctl的designer时,十多分钟挂了2次,每次挂了之后就签不出来了,只能等半小时,然后在taskctl的QQ群里咨询了,给的解决方案是 http://www.taskctl.co ...