程序启动时查找所有注册了的apps.py 会执行def ready方法
MyAdmin.apps.py:
def ready(self):
super(MyadminConfig,self).ready()

from django.utils.module_loading import autodiscover_modules
autodiscover_modules('reg')

这里应该是收集所有的reg文件。执行reg.py中的注册函数
app01.reg.py:
from app01 import models
from MyAdmin.service import v1
#执行v1.site.register方法,将model_class传入
v1.site.register(models.UserInfo)
v1.site.register(models.Role)

MyAdmin.service.v1.py:
#site为MySite对象
site = MySite()
#通过执行并传入model的register函数,生成一个字典并保存:
ret={
"UserInfo":BaseAdmin(UserInfo,site)
"Role":BaseAdmin(Role,site)
}
def register(self,model_class,xxx = BaseAdmin):
self._registry[model_class] = xxx(model_class,self)


Django.urls.py:
from django.conf.urls import url
from MyAdmin.service import v1
urlpatterns = [
url(r'^md/', v1.site.urls),
]
当Django启动后,这里使用路由分发的原理 v1.site.urls 分发了预设的url以及
根据app名称跟类名拼接生成的url,在此基础上再次分发,使每个类都有
4个url:changelist、add、delete、change
MyAdmin.service.v1.py class

@property
1. def urls(self):
return self.get_urls(),self.app_name,self.namespace


2. def get_urls(self):
from django.conf.urls import url,include
ret = [
url(r'^login/',self.login,name='login'),
url(r'^logout/',self.login,name='logout'),
]
"""
model_cls为models类,admin_obj为BaseAdmin(model类, MySite()即site ),即传入2个参数的BaseAdmin对象,
admin_obj.urls则执行BaseAdmin的urls方法
"""
for model_cls,admin_obj in self._registry.items():
app_label = model_cls._meta.app_label
model_name = model_cls._meta.model_name

ret.append(url(r'^%s/%s' % (app_label,model_name),include(admin_obj.urls)))

return ret

3.@property
def urls(self):
from django.conf.urls import url,include
info = self.model_class._meta.app_label,self.model_class._meta.model_name
"""

  

这里的self.model_class为之前传入的model类,所以一样可以取得app和model类名,由此设置别名,
方便后续反向生成url.
"""
urlpatterns = [
url(r'^$',self.changelist_view,name='%s_%s_changelist' % info),
url(r'^add/$',self.add_view,name='%s_%s_add' % info),
url(r'^(.+)/delete/$',self.delete_view,name='%s_%s_delete' % info),
url(r'^(.+)/change/$',self.change_view,name='%s_%s_change' % info),
]
return urlpatterns


生成url后,我们需要对每个url指定不同的操作,以changelist为例子,每个类定义的字段,以及字段名都不同,我们又不可能为每一个类的url做单独的模版,假如有几十个类,这样增删改查工作量太大,因此我们需要为每个类的增删改查做统一的视图模版.

阶段一代码:

1.目录结构:

Django仿Admin定制插件(一)Django仿Admin定制插件(一)

 

2.代码:

  1 from django.http import HttpResponse
  2 from django.shortcuts import render
  3 
  4 class BaseAdmin(object):
  5     list_display = "__all__"
  6 
  7     def __init__(self,model_class,site):
  8         self.model_class = model_class
  9         self.site = site
 10         self.request = None
 11 
 12     @property
 13     def urls(self):
 14         from django.conf.urls import url
 15         """
 16         这里的self.model_class为之前传入的model类,所以一样可以取得app和model类名,由此设置别名,
 17         方便后续反向生成url.
 18         """
 19         info = self.model_class._meta.app_label,self.model_class._meta.model_name
 20         urlpatterns = [
 21             url(r'^$',self.changelist_view,name='%s_%s_changelist' % info),
 22             url(r'^add/$',self.add_view,name='%s_%s_add' % info),
 23             url(r'^(.+)/delete/$',self.delete_view,name='%s_%s_delete' % info),
 24             url(r'^(.+)/change/$',self.change_view,name='%s_%s_change' % info),
 25         ]
 26         return urlpatterns
 27 
 28     def add_view(self,request):
 29         """
 30         新增数据
 31         :param request:
 32         :return:
 33         """
 34         info = self.model_class._meta.app_label,self.model_class._meta.model_name
 35         data = "%s_%s_add" % info
 36         return HttpResponse(data)
 37 
 38     def delete_view(self,request,pk):
 39         """
 40         删除数据
 41         :param request:
 42         :return:
 43         """
 44         # self.model_class.objects.filter(id=pk).delete()
 45         info = self.model_class._meta.app_label, self.model_class._meta.model_name
 46         data = "%s_%s_del" % info
 47         return HttpResponse(data)
 48 
 49     def change_view(self,request,pk):
 50         """
 51         修改数据
 52         :param request:
 53         :return:
 54         """
 55         info = self.model_class._meta.app_label, self.model_class._meta.model_name
 56         data = "%s_%s_change" % info
 57         return HttpResponse(data)
 58 
 59     def changelist_view(self,request):
 60         """
 61         查看列表
 62         :param request:
 63         :return:
 64         """
 65         self.request = request
 66         result_list = self.model_class.objects.all()
 67         context = {
 68             'result_list':result_list,
 69             'list_display':self.list_display,
 70             'admin_obj':self  #此处self为自定制的Admin-models类对象
 71         }
 72         return render(request,'md/change_list.html',context)
 73 
 74 
 75 class MySite(object):
 76     def __init__(self):
 77         self._registry = {}
 78         self.namespace = 'MyAdmin'
 79         self.app_name = 'MyAdmin'
 80 
 81     def register(self,model_class,xxx = BaseAdmin):
 82         self._registry[model_class] = xxx(model_class,self)
 83         """{
 84         modle类:BaseAdmin(model类, MySite()即site )
 85         }
 86         """
 87 
 88     def get_urls(self):
 89         from django.conf.urls import url,include
 90         ret = [
 91             url(r'^login/',self.login,name='login'),
 92             url(r'^logout/',self.login,name='logout'),
 93         ]
 94         #通过循环items获得每一个model类所在的app名,以及小写的类名
 95         for model_cls,admin_obj in self._registry.items():
 96             """
 97             model_cls为models类,admin_obj为BaseAdmin(model类, MySite()即site ),即传入2个参数的BaseAdmin对象,
 98             admin_obj.urls则执行BaseAdmin的urls方法
 99             """
100             app_label = model_cls._meta.app_label
101             model_name = model_cls._meta.model_name
102             # print(app_label,model_name)
103             #拼接生成url,如/md/app01/userinfo/,再次分发拿到最终的/md/app01/userinfo/change_list等url
104             ret.append(url(r'^%s/%s' % (app_label,model_name),include(admin_obj.urls)))
105 
106         return ret
107 
108     @property
109     def urls(self):
110         return self.get_urls(),self.app_name,self.namespace
111 
112     def login(self,request):
113         return HttpResponse('login')
114 
115 site = MySite()
MyAdmin.service.v1

相关文章:

  • 2022-12-23
  • 2021-09-28
  • 2019-03-19
  • 2021-08-01
  • 2022-12-23
  • 2021-12-28
猜你喜欢
  • 2021-05-28
  • 2022-12-23
  • 2021-10-26
  • 2022-01-26
  • 2022-12-23
  • 2021-09-06
  • 2021-12-02
相关资源
相似解决方案