自定义组件类注册

编辑本博客

stark/service/stark.py

from django.urls import re_path,path
from django.shortcuts import HttpResponse
class StarkConfig(object):
    def __init__(self,model_class):
        self.model_class=model_class
        self.site=site
    #对表的操作方法,增、删、改、查
    def changelist_view(self,request):
        return HttpResponse("%s.%s" % (self.model_class._meta.app_label,self.model_class._meta.model_name))
    def add_view(self,request):
        pass
    def change_view(self,request,pk):
        pass
    def delete_view(self,request,pk):
        pass
    #创建类的方法,获取该类相关urls,这里不同的app进来对应的self就不一样
    def get_urls(self):
        info=self.model_class._meta.app_label,self.model_class._meta.model_name
        urlpatterns=[
            re_path(r'^list/$',self.changelist_view,name='%s_%s_changelist' % info),
            re_path(r'^add/$',self.add_view,name='%s_%s_add' % info),
            re_path(r'^(?P<pk>\d+)change/$',self.change_view,name='%s_%s_change' % info),
            re_path(r'^(?P<pk>\d+)del/$',self.delete_view,name='%s_%s_del' % info),
        ]
        extra=self.extra_url()
        if extra:
            #扩展urls
            urlpatterns.append(extra)
        return urlpatterns
    #钩子函数,可以在子类中自定义该方法,对urls进行扩展
    def extra_url(self):
        pass
    @property#该装饰器使调用该方法时直接用函数名即可,无需加括号
    def urls(self):
        return self.get_urls()
#自定义注册类
class AdminSite(object):
    def __init__(self):
        self._registry={}#用于存储注册进来的类,key是类,值是StarkConfig或自定义的StarkConfig的子类
        self.app_name='stark'
        self.namespace='stark'
    #函数注册方法
    def register(self,models_class,stark_config=None):
        if not stark_config:
            stark_config=StarkConfig
        self._registry[models_class]=stark_config(models_class)
    #动态创建urls
    def get_urls(self):
        urlpatterns=[]
        for k,v in self._registry.items():
            #对注册的类进行循环,创建urls
            app_label=k._meta.app_label
            model_name=k._meta.model_name
            #v.urls是StarkConfig或自定义的StarkConfig的子类的urls,对路由进行再分发
            urlpatterns.append(re_path(r"^%s/%s/" % (app_label,model_name,),(v.urls,None,None)))
        return urlpatterns
    @property
    def urls(self):
        #返回一个元祖,这里返回内容就和include()方法返回的内容一样
        return self.get_urls(),self.app_name,self.namespace

#实例化注册类,需要注册的时候,导入该实例对象即可,大家操作的都是同一个实例对象
site=AdminSite()
View Code

stark.py修改版本,通过wrapper对视图函数进行装饰,可以批量添加功能

from functools import wraps
from django.urls import re_path,path
from django.shortcuts import HttpResponse
class StarkConfig(object):
    def __init__(self,model_class):
        self.model_class=model_class
        self.site=site
    #对表的操作方法,增、删、改、查
    def changelist_view(self,request):
        return HttpResponse("%s.%s" % (self.model_class._meta.app_label,self.model_class._meta.model_name))
    def add_view(self,request):
        pass
    def change_view(self,request,pk):
        pass
    def delete_view(self,request,pk):
        pass
    #自定义内部钩子装饰器,让所有url进来都走这个函数,就可以批量添加功能
    def wrapper(self,func):
        @wraps(func)#保留原函数信息
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    #创建类的方法,获取该类相关urls,这里不同的app进来对应的self就不一样
    def get_urls(self):
        info=self.model_class._meta.app_label,self.model_class._meta.model_name
        urlpatterns=[
            re_path(r'^list/$',self.wrapper(self.changelist_view),name='%s_%s_changelist' % info),
            re_path(r'^add/$',self.wrapper(self.add_view),name='%s_%s_add' % info),
            re_path(r'^(?P<pk>\d+)change/$',self.wrapper(self.change_view),name='%s_%s_change' % info),
            re_path(r'^(?P<pk>\d+)del/$',self.wrapper(self.delete_view),name='%s_%s_del' % info),
        ]
        extra=self.extra_url()
        if extra:
            #扩展urls
            urlpatterns.append(extra)
        return urlpatterns
    #钩子函数,可以在子类中自定义该方法,对urls进行扩展
    def extra_url(self):
        pass
    @property#该装饰器使调用该方法时直接用函数名即可,无需加括号
    def urls(self):
        return self.get_urls()
#自定义注册类
class AdminSite(object):
    def __init__(self):
        self._registry={}#用于存储注册进来的类,key是类,值是StarkConfig或自定义的StarkConfig的子类
        self.app_name='stark'
        self.namespace='stark'
    #函数注册方法
    def register(self,models_class,stark_config=None):
        if not stark_config:
            stark_config=StarkConfig
        self._registry[models_class]=stark_config(models_class)
    #动态创建urls
    def get_urls(self):
        urlpatterns=[]
        for k,v in self._registry.items():
            #对注册的类进行循环,创建urls
            app_label=k._meta.app_label
            model_name=k._meta.model_name
            #v.urls是StarkConfig或自定义的StarkConfig的子类的urls,对路由进行再分发
            urlpatterns.append(re_path(r"^%s/%s/" % (app_label,model_name,),(v.urls,None,None)))
        return urlpatterns
    @property
    def urls(self):
        #返回一个元祖,这里返回内容就和include()方法返回的内容一样
        return self.get_urls(),self.app_name,self.namespace

#实例化注册类,需要注册的时候,导入该实例对象即可,大家操作的都是同一个实例对象
site=AdminSite()
View Code

在其他app中创建stark.py文件,在这里对该app的models进行注册

from app02 import models
from stark.service.stark import site
site.register(models.Permission)
View Code

在另一个app中的stark.py文件中,自定义StarkConfig的子类,注册app的models时传入

这里自定义后,重写父类的extra_url方法,来扩展url

from app01 import models
from django.urls import re_path
from django.shortcuts import HttpResponse,render
from stark.service.stark import site,StarkConfig
def test(request):
    return HttpResponse('扩展URL')
class UserinfoConf(StarkConfig):
    def extra_url(self):
        return re_path(r'test/',test)
site.register(models.UserInfo,UserinfoConf)
View Code

在项目的urlpatterns中添加一个路由

 

posted @ 2018-09-04 16:36  丫丫625202  阅读(110)  评论(0编辑  收藏  举报