当django一启动的时候,django自带一些URL,并可以访问,有相应的页面。如:admin/ url是django自带,以及admin里面所有的操作 login logout 以及编辑操作的URL。
自定义django框架步骤:------数据查看-------
当django程序启动时首先会每个app下的apps.py--下的 ready() 方法,
默认的apps.py
from django.apps import AppConfig class App0Config(AppConfig): name = 'app0'
修改apps.py, 让ready()自动去找 自己定义的custom 而不是自带的admin.py文件 。 ###如果admin.py文件也可以 ,只要是自定制的
from django.apps import AppConfig class App01Config(AppConfig): name = 'app01' def ready(self): """ 当程序运行时,django会找每个APP的apps.py的ready 方法 :return: """ super(App01Config,self).ready() from django.utils.module_loading import autodiscover_modules autodiscover_modules('custom')
自定制admin.py ---->custom.py
print('custom app01') from app03.service import v1 #实现注册方法的是v1 from app01 import models v1.site.register(models.App02Userinfo)#
print('cusmtom app02') from app03.service import v1 from app02 import models from django.utils.safestring import mark_safe class display_oprate(v1.BaseCustom): def func(self, obj=None,is_header=False): if is_header: return '操作' else: """ 显示操作字段 """ from django.urls import reverse name = "{namespace}:{appname}_{modelname}_change".format(namespace=self.site.namespace, appname=self.model_class._meta.app_label, modelname=self.model_class._meta.model_name) url = reverse(name, args=(obj.pk,)) # reverse{namespace:} return mark_safe("<a href='{0}'>编辑</a>".format(url)) def checkbox(self, obj=None,is_header=False): if is_header: return mark_safe("<input type='checkbox'/>") else: tag = '<input type="checkbox" value="{0}" />'.format(obj.pk) return mark_safe(tag) list_display = [checkbox, 'id', 'username','email', func] class Display_userinfo(v1.BaseCustom): list_display=['id','username','email'] class Display_Role(v1.BaseCustom): def func(self, obj): """ 显示操作字段 """ from django.urls import reverse name = "{namespace}:{appname}_{modelname}_change".format(namespace=self.site.namespace, appname=self.model_class._meta.app_label, modelname=self.model_class._meta.model_name) url = reverse(name, args=(obj.pk,)) # reverse{namespace:} return mark_safe("<a href='{0}'>编辑</a>".format(url)) def checkbox(self, obj): tag = '<input type="checkbox" value="{0}" />'.format(obj.pk) return mark_safe(tag) list_display = [checkbox, 'id', 'title', func] ,这里就是页面上要显示的字符 class Display_test1(v1.BaseCustom): def func(self,obj): """ 显示操作字段 """ from django.urls import reverse name="{namespace}:{appname}_{modelname}_change".format(namespace=self.site.namespace,appname=self.model_class._meta.app_label,modelname=self.model_class._meta.model_name) url=reverse(name,args=(obj.pk,))# reverse{namespace:} return mark_safe("<a href='{0}'>编辑</a>".format(url)) def checkbox(self,obj): tag='<input type="checkbox" value="{0}" />'.format(obj.pk) return mark_safe(tag) list_display = [checkbox,'id','title',func] v1.site.register(models.UserInfo,display_oprate) #在页面上要显示操作“编辑”链接,在注册的时个就传入进去,并在v1.py里接收这个参数如下:
context={ 'result_list':result_list, 'list_display':self.list_display, 'display_change':self }
v1.site.register(models.Role,Display_Role) v1.site.register(models.test1,Display_test1)
目录结构:
自定制的admin v1 文件存储在app03里面。
from django.shortcuts import HttpResponse,render,redirect class BaseCustom(object): # list_display = ['id','name'] list_display = "__all__" def __init__(self,model_class,site): self.model_class=model_class self.site=site self.request=None @property def urls(self): from django.conf.urls import url,include info=self.model_class._meta.app_label,self.model_class._meta.model_name 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 def changelist_view(self,request): """ 查看列表 :param request: :return: """ self.request=request result_list=self.model_class.objects.all() context={ 'result_list':result_list, 'list_display':self.list_display, 'display_change':self } return render(request,'custum/change_list.html',context) def add_view(self,request): data='add_view' return HttpResponse(data) def delete_view(self,reqeust): """ :param reqeust: :return: """ info=self.model_class._meta.app_label,self.model_class._meta.model_name data="%s_%s_del"%info return HttpResponse(data) def change_view(self,request): info = self.model_class._meta.app_label, self.model_class._meta.model_name data="%s_%s_change_view"%info return HttpResponse(data) class Custom(object): def __init__(self): self._registry={} self.namespace='custom' self.app_name='custom' def register(self,model_class,xx=BaseCustom): #注册方法如admin.site.register(models.Role) model_clss类也就是表的名称, """_registry { _registry[model.Role]:obj } """ self._registry[model_class]=xx(model_class,self) print(self._registry,self,'----') """ app名称models类名:BaseCustom 类封装了 app名称models类名,site对象 {<class 'app02.models.Role'>: <app03.service.v1.BaseCustom object at 0x106149c18>, <class 'app01.models.App02Userinfo'>: <app03.service.v1.BaseCustom object at 0x1061499b0>} {<class 'app02.models.Role'>: <app03.service.v1.BaseCustom object at 0x106149c18>, <class 'app01.models.App02Userinfo'>: <app03.service.v1.BaseCustom object at 0x1061499b0>, <class 'app02.models.test1'>: <app03.service.v1.BaseCustom object at 0x106149940>} """ def get_urls(self): from django.conf.urls import url,include ret=[ # url(r'login/',self.login,name='login'), # url(r'logout/',self.logout,name='logout'), ] for model_cls,admin_obj in self._registry.items(): print(model_cls,model_cls._meta.app_label,'---',model_cls._meta.model_name) #app名字 #模块名字 app_labe=model_cls._meta.app_label model_name=model_cls._meta.model_name ret.append(url(r'%s/%s/'%(app_labe,model_name), include(admin_obj.urls))) #反生成,当每个APP的URL进来时,每个APP都 有 #自己的增删改查。 return ret def login(self,request): return HttpResponse('login') def logout(self,request): return HttpResponse('logout') @property def urls(self): return self.get_urls(),self.app_name,self.namespace site=Custom() #site对象
前端展示:
change_list.html :
{% load custom_list %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>数据列表</title> </head> <body> <h3>数据</h3> <h3>{% func result_list list_display display_change %} </h3> </body> </html>
扩展模板:
from django.template import Library from types import FunctionType register=Library() def inner(result_list,list_display,display_change): for row in result_list: # yield [getattr(row,name) for name in list_display] yield [name(display_change,obj=row) if isinstance(name,FunctionType) else getattr(row,name) for name in list_display] def table_head(list_display,display_change): head_list = [] for item in list_display: if isinstance(item, FunctionType): # head_list.append(item.__name__.title()) yield item(display_change, is_header=True) else: yield display_change.model_class._meta.get_field(item).verbose_name # item 类型 "username" "email" "id" @register.inclusion_tag('custum/md.html')#表示要导入一个HTML模板,下面的返回值表示给这个模板使用 def func(result_list,list_display,display_change): v=inner(result_list,list_display,display_change) h=table_head(list_display,display_change) return {'name':v,'name2':h}
自定制框架--admin---- 增加
custom-list.py
from django.template import Library from types import FunctionType register=Library() def inner(result_list,list_display,display_change): print(result_list,'===') #<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>]> for i in result_list: print([str(i)],'------') for row in result_list: if list_display=='__all__': yield [str(row),] #['UserInfo object'] else: # yield [getattr(row,name) for name in list_display] yield [name(display_change,obj=row) if isinstance(name,FunctionType) else getattr(row,name) for name in list_display] def table_head(list_display,display_change): for item in list_display: if isinstance(item, FunctionType): # head_list.append(item.__name__.title()) yield item(display_change, is_header=True) else: yield display_change.model_class._meta.get_field(item).verbose_name # item 类型 "username" "email" "id" @register.inclusion_tag('custum/md.html')#表示要导入一个HTML模板,下面的返回值表示给这个模板使用 def func(result_list,list_display,display_change): v=inner(result_list,list_display,display_change) h=table_head(list_display,display_change) return {'name':v,'name2':h}
v1.py
def changelist_view(self,request): """ 查看列表 :param request: :return: """ #生成页面上的添加按钮: #需要的元素: namespace:app_label ,model_name reverse #self.site.namespace #self.model_class._meta.app_label from django.http.request import QueryDict print(request.GET.urlencode()) param_dict=QueryDict(mutable=True) if request.GET: param_dict['_changelistfilter']=request.GET.urlencode() print(param_dict.urlencode()) base_add_url=reverse("{2}:{0}_{1}_add".format(self.app_label,self.model_name,self.site.namespace)) add_url="{0}?{1}".format(base_add_url,param_dict.urlencode()) self.request=request result_list=self.model_class.objects.all() context={ 'result_list':result_list, 'list_display':self.list_display, 'display_change':self, 'add_url':add_url } return render(request,'custum/change_list.html',context)
添加操作:
def add_view(self,request): """ 添加数据 :param request: :return: """ print(request.GET('_changelistfilter')) if request.method=='GET': model_form_obj=self.get_add_or_edit_model_form()() else: model_form_obj=self.get_add_or_edit_model_form()(data=request.POST,files=request.FILES) if model_form_obj.is_valid(): model_form_obj.save() #添加成功,跳转页面 #/custom/app01/userinfo/+request.GET.get('_changelistfileter') base_list_url = reverse("{2}:{0}_{1}_changelist".format(self.app_label, self.model_name, self.site.namespace)) list_url = "{0}?{1}".format(base_list_url, request.GET('_changelistfilter')) return redirect(list_url) from django.forms import ModelForm model_form_cls=self.get_add_or_edit_model_form() context={ 'form':model_form_cls, } data='add_view' return render(request,'custum/add.html',context)
add.html
<h3>添加数据</h3> <form method="post">{% csrf_token %} {{ form.as_p }} <input type="submit" value="提交"> </form>
修改功能:
def change_view(self,request,pk): obj=self.model_class.objects.filter(pk=pk).first() if not obj: return HttpResponse('id不存在 ') if request.mthod=='GET': model_form_obj = self.get_add_or_edit_model_form()(instance=obj) else: model_form_obj=self.get_add_or_edit_model_form()(data=request.POST,instance=obj) context={ 'form':model_form_obj } return render(request,'custum/edit.html',context)