自定义组件类注册
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()
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()
在其他app中创建stark.py文件,在这里对该app的models进行注册
from app02 import models from stark.service.stark import site site.register(models.Permission)
在另一个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)
在项目的urlpatterns中添加一个路由