bbs-admin-自定义admin(一)
自定义admin
概要:django-admin本质就是一个app,只是Django内部分装了,因此我们尝试自己设计一个简易版的admin
设计前知识补充:
model._meta.app_label:获该类所在的app名
model._meta.model_name:获该类的类名
model:类
config_obj:配置类对象对象
设计思路
1 在uls.py文件中,模仿admin url(r'^admin/', admin.site.urls)
我们可以设计一个名为stark的app,
2 创建stark模块,基础配置按app方法来,其中创建一个servers文件,写我们自己的模块
3 按照admin源码解析的思路:启动--->注册----->url设计
4 启动:
1 扫描 ---{扫描所有app下的stark文件}
这里有个ready函数,在启动时执行,我们利用这个函数完成扫描功能
在apps.py下
from django.apps import AppConfig from django.utils.module_loading import autodiscover_modules class StarkConfig(AppConfig): name = 'stark' def ready(self): autodiscover_modules('stark')
注册
目的:将所有的模型类,及模型类对象,以键值对的形式保存在site._registry
这里需要一个单例模式的对象site,及默认模型类
在stark下的servers文件下的sites文件进行设计
# 默认模型类 class ModelStark: pass # 单例site模型类 class StarkSite(object): def __init__(self): self._registry = {} def register(self ,model ,admin_class=None): if not admin_class: admin_class = ModelStark self._registry[model] = admin_class(model) site = StarkSite()
然后在app下的stark文件下进行注册
from stark.servers import sites from app01.models import Author, Book, Publish, AuthorDetail sites.site.register(Author) class BookConfig(sites.ModelStark): list_display = ['title','price'] sites.site.register(Book,BookConfig) sites.site.register(Publish) sites.site.register(AuthorDetail)
如果我们需要自定义模型
按照admin的方式来就行了,只不过继承的是我们定义的默认模型类
url设计
参考多级路由:
难点:三级路由
url_list = url(r'{}/{}/'.format(model._meta.app_label,model._meta.model_name),config_obj.urls)
解析:config_obj:配置类对象对象,我们在配置类对象中设计三级路由,及所对应的视图函数
优点:我们可以从视图函数中直接取到配置类的对象,由于 self.model = model 我们还可以取到对应的表
实际操作:
urls.py中
urlpatterns = [ url(r'^admin/', admin.site.urls), # # url(r'index',([ # url(r'^$',index), # url(r'test01',test01), # url(r'test02',test02) # ],None,None)) url(r'^stark/', sites.site.urls) ]
自定义的sites.py中
from django.conf.urls import url from django.shortcuts import render, HttpResponse, redirect class ModelStark: list_display = [] def __init__(self,model): self.model = model def show(self,request): print('>>>>>>>',self.model,self.list_display) show_obj = self.model.objects.all() return render(request,'show.html',{'show_obj':show_obj}) def add(self,request): add_obj = self.model.objects.all() return render(request,'add.html',{'add_obj':add_obj}) def change(self,request,id): change_obj = self.model.objects.all() return render(request,'change.html',{'change_obj':change_obj}) def delete(self,request,id): delete_obj = self.model.objects.all() return render(request,'delete.html',{'delete_obj':delete_obj}) def get_urls(self): item = [ url(r'^$',self.show), url(r'add/',self.add), url(r'(\d+)/change/', self.add), url(r'(\d+)/delete', self.delete), ] return item @property def urls(self): return self.get_urls(),None,None class AdminSite(object): def __init__(self): self._registry = {} def register(self ,model ,admin_class=None): if not admin_class: admin_class = ModelStark self._registry[model] = admin_class(model) def get_urls(self): item = [] for model, config_obj in self._registry.items(): url_list = url(r'{}/{}/'.format(model._meta.app_label,model._meta.model_name),config_obj.urls) item.append(url_list) print('--->',item) return item @property def urls(self): # print('----000--->',self._registry) return self.get_urls(), None, None site = AdminSite()