Django之Xadmin
先回顾admin的启动流程:
- 启动:加载admin组件,配置urls使网页可以访问到
- 注册:admin.site.register(model),注册以后就可以增删改查这个表了
- 设计:为每一个表设计增删改查url
设计思想
Django一启动,Xadmin的site对象最终是要设计出注册model的增删改查四个url。
/app01/book/
/app01/book/add
/app01/book/id/delete
/app01/book/id/change
等于是urls.py中, url(r'^Xadmin/', site.urls)一行就要返回所有的model增删改查等页面
使用流程
使用流程基本上都是仿照admin
1. 加载组件
既然是一个app就需要在配置文件里安装一下
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'Xadmin.apps.XadminConfig', # 加载Xadmin下的apps.py里的XadminConfig类 'app01.apps.App01Config', 'app02.apps.App02Config', ]
2. 自动发现
XadminConfig自动发现所有叫Xadmin的模块并加载
apps.py:
from django.apps import AppConfig from django.utils.module_loading import autodiscover_modules class XadminConfig(AppConfig): name = 'Xadmin' def ready(self): # 这个类被加载的时候会执行这个方法。 autodiscover_modules('Xadmin') # 自动发现并加载应用下所有Xadmin的模板
3. 注册的单例类(精简版)
仿照admin为Xadmin写一个注册的类 Xadmin/service/Xadmin.py 位置随便写哪都行
admin使用思路回顾:
- 启动Xadmin(已完成)
- 注册model(写一个注册的类)
- 为注册的model设计增删改查四个urls。(写一个设计urls的类)
from django.conf.urls import url from django.shortcuts import render, HttpResponse, redirect class ModelXadmin(object): def __init__(self, model, site): self.model = model self.site = site @property def urls2(self): return self.get_urls2(), None, None def get_urls2(self): temp = [] temp.append(url(r"^$", self.list_view)) temp.append(url(r"^add/$", self.add_view)) temp.append(url(r"^(d+)/change/$", self.change_view)) temp.append(url(r"^(d+)/delete/$", self.delete_view)) return temp def list_view(self, request): all_obj = self.model.objects.all() return render(request, 'list_view.html', {'all_obj': all_obj}) def add_view(self, request): return render(request, 'add_view.html') def change_view(self, request, id): return render(request, 'change_view.html') def delete_view(self, request, id): return render(request, 'delete_view.html') class XadminSite(): def __init__(self): self._register = {} # ②注册model的函数,传入model和model的自定义类 def register(self, model, admin_class=None, **options): if not admin_class: admin_class = ModelXadmin # ③key是model,设计url的时候取app名字和类名 # values是样式对象,设计二级url,哪个model就设计哪个model的增删改查,然后就好取值了 self._register[model] = admin_class(model, self) # ④ 开始设计model的增删改查url(r'^Xadmin/', site.urls) @property def urls(self): return self.get_urls(), None, None # ⑤ 第一次url分发,它是什么样的? /app01/book/ /app02/order/ def get_urls(self): temp = [] # 肯定返回列表 # ⑥ 循环self._register, key是model,value是样式对象 for model, admin_class_obj in self._register.items(): app_name = model._meta.app_label model_name = model._meta.model_name # ⑦ 第二次url分发,返回了每个模型的增删改查页面和对应执行函数 temp.append(url(r'^{0}/{1}/'.format(app_name, model_name), admin_class_obj.urls2)) return temp # ①单例模式对象,所有app的model都使用这个对象注册 site = XadminSite()
4. 激活组件
from Xadmin.service.Xadmin import site urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^Xadmin/', site.urls), ]
5. 查询代码示例
def list_view(self, request): print("self.model", self.model) # 用户访问哪张表,self.model就是谁。 model_name=self.model._meta.model_name data_list = self.model.objects.all() print("list_display:",self.list_display) ## ['title', 'prcie'] # 处理表头 #header_list=["ID","书籍名称","出版社"] header_list=[] for field in self.list_display: # [check,"nid","title","publish",edit,delete] if isinstance(field,str): if field=="__str__": val= self.model._meta.model_name.upper() else: field_obj=self.model._meta.get_field(field) val=field_obj.verbose_name else: val=field(self,is_header=True) # 获取表头,传is_header=True header_list.append(val) # 处理表单数据, 处理成一个大列表, 里面是一个个小列表 new_data_list=[] for obj in data_list: # data_list [book_obj,book_obj2,...] temp=[] for field in self.list_display: # ['title', 'prcie',edit,delete] if isinstance(field,str): val=getattr(obj,field) else: val=field(self,obj) temp.append(val) new_data_list.append(temp) ''' new_data_list=[ ["北京折叠",122,<a href=''>编辑</a>,<a href=''>删除</a>], ["三体", 222,<a href=''>编辑</a>,<a href=''>删除</a>], ] ''' return render(request, 'list_view.html', {"new_data_list": new_data_list,"model_name":model_name,"header_list":header_list})