博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
公用插件开发-Day2
阅读量:4449 次
发布时间:2019-06-07

本文共 5466 字,大约阅读时间需要 18 分钟。

如何实现注册model?

在app_plug中创建service文件夹,创建v1.py用于接收,封装,和处理model,此处我们首先需要实现的是接收,封装,具体做法如下:

class BasePlugModel:    def __init__(self, model_class, site):        self.model_class = model_class        self.site = siteclass AppPlugSite(object):    def __init__(self):        self._registry = {}        self.app_name = "app_plug"        self.namespace = "app_plug"    def register(self, model_class, app_plug_model_class=BasePlugModel):        self._registry[model_class] = app_plug_model_class(model_class, self)

在别的app中注册model时只需要:

v1.site.register(models.UserInfo)

自动生成URL

对于此类问题肯定要首先解决路由分发的问题,以前运用include函数可以将URL分层管理,进入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)

大部分地方可以不用管,我们需要了解的是他的返回值,返回值的属性分别为:url关系列表或模块(模块内部必须有urlpatterns属性);app_name;namespace

了解了返回值之后我们可以自己写一个函数来模仿include函数所做的事,其实这个函数的返回值和include函数的返回值要求相同即可,在AppPlugSite类中创建

def urls(self):        """        创建URL对应关系        :return: 元组类型:url关系列表或模块(模块内部必须有urlpatterns属性);app_name;namespace        """        return self.get_urls(), self.app_name, self.namespace

然后要处理的就是get_urls函数该怎么写,首先要明确的时这个函数的返回值一定是个列表类型,简单的写:

def get_urls(self):        """        封装url至列表        :return: 装有url的列表        """        from django.conf.urls import include        from django.urls import re_path        # urlpatterns变量名不能更改,因为include内部实现寻找url时就是查找urlpatterns变量获取        urlpatterns = [            # url(r'^$', self.index, name='index'),            re_path(r'^login/$', self.login, name='login'),            re_path(r'^logout/$', self.logout, name='logout'),        ]        return urlpatterns

然后在urls.py中添加:

re_path(r'^plug/', v1.site.urls),

这样就添加了一些二级的URL,但是我们所要做的是要对任何数据列表进行增删改查的操作,URL格式应该为:http://127.0.0.1:8000/plug/app01/userinfo/1/delete/ 这样的,这个URL所含的信息有包名,models的类名,还有操作方式和操作对象id

获取包名和类名的方法为: 类._meta.app_label,类._meta.model_name,这样在BasePlugModel类中再创建:

def another_urls(self):        """        钩子函数,用于自定义额外的URL        :return:        """        return []    def get_urls(self):        """        配置最后一段URL用于增删改查等操作        :return:        """        from django.urls import re_path        # 获取包名和类名,方便日后反向生成URL        info = self.model_class._meta.app_label, self.model_class._meta.model_name        urlpatterns = [            re_path(r'^$', self.list_view, name='%s_%s_list' % info),            re_path(r'^add/$', self.add_view, name='%s_%s_add' % info),            re_path(r'^(.+)/delete/$', self.delete_view, name='%s_%s_delete' % info),            re_path(r'^(.+)/change/$', self.change_view, name='%s_%s_change' % info),            # re_path(r'^(.+)/detail/$', self.detail_view, name='%s_%s_detail' % info),        ]        urlpatterns += self.another_urls()        return urlpatterns    @property    def urls(self):        return self.get_urls()

这样,就可以对任何数据列表进行增删改查的操作。

在AppPlugSite中的完整的get_urls函数为:

def get_urls(self):        """        封装url至列表        :return: 装有url的列表        """        from django.conf.urls import include        from django.urls import re_path        # urlpatterns变量名不能更改,因为include内部实现寻找url时就是查找urlpatterns变量获取        urlpatterns = [            # url(r'^$', self.index, name='index'),            re_path(r'^login/$', self.login, name='login'),            re_path(r'^logout/$', self.logout, name='logout'),        ]        # 根据model动态生成URL        for model_class, plug_model_obj in self._registry.items():            # 获取包名和类名            app_label = model_class._meta.app_label            model_name = model_class._meta.model_name            # 拼接URL            urlpatterns += [re_path(r'^%s/%s/' % (app_label, model_name), include(plug_model_obj.urls)), ]        return urlpatterns

  

转载于:https://www.cnblogs.com/yu-jie/p/9405059.html

你可能感兴趣的文章
类的继承、菱形继承、派生、多态
查看>>
mysql约束
查看>>
javascript鼠标及键盘事件总结及案例
查看>>
mysql表之间的关系及级联操作
查看>>
mac 搭建virtualenv的那些坑
查看>>
多路复用IO模型
查看>>
并发、串行、并行及多道技术原理
查看>>
hashlib、pickle、hmac、logging模块使用
查看>>
javascript常用知识点总结
查看>>
2019秋招复习笔记--数据库基本操作
查看>>
2019秋招复习笔试--手写代码
查看>>
2019秋招复习笔记--智力题
查看>>
MySQL学习笔记
查看>>
2019秋招面试复习 项目重点提问
查看>>
面试题
查看>>
DS博客作业08-课程总结
查看>>
利用Python爬虫刷店铺微博等访问量最简单有效教程
查看>>
浅谈软件测试与墨菲定律
查看>>
文件安全复制之 FastCopy
查看>>
强烈推荐美文之《从此刻起,我要》
查看>>