以往建立了一张表,需要
1.为每张表创建4个url
2.为每张表创建4个视图函数
1 urlpatterns = [ 2 url('^role/list/$',role.role_list,name='role_list'), 3 url('^role/add/$',role.role_add,name='role_add'), 4 url('^role/edit/(?P<pk>d+)/$',role.role_edit,name='role_edit'), 5 url('^role/del/(?P<pk>d+)/$',role.role_del,name='role_del'), 6 ]
如果我们需要对大量的表进行这些操作,虽简单但是耗费时间和精力,且不保证细节会百分百正确。再有的是 程序狗为写重复的代码可耻!
现在:为app中的每个model类自动创建URL以及相关视图函数

1 def url(regex, view, kwargs=None, name=None): 2 return re_path(regex, view, kwargs, name)
返回值主要参数为regex ,view
前面的StarkSite类中,同样是regex , view
if prev: patterns.append(url(r'^%s/%s/%s/'%(app_name,model_name,prev),(handler.get_urls(),None,None))) else: patterns.append(url(r'^%s/%s/' % (app_name, model_name), (handler.get_urls(), None,None)))
prev前缀。(默认prev=None)使用者可以通过导入参数prev,实现正则不同前缀的url。
在StarkHandler类中get_urls生成相关视图函数:
1 def get_urls(self): 2 """ 3 生成视图函数 4 :return: 5 """ 6 patterns = [ 7 url(r'^list/$', self.wapper(self.list_view), name=self.get_list_url_name), 8 url(r'^add/$', self.wapper(self.add_view), name=self.get_add_url_name), 9 url(r'^change/(?P<pk>d+)/$', self.wapper(self.change_view), name=self.get_change_url_name), 10 url(r'^delete/(?P<pk>d+)/$', self.wapper(self.delete_view), name=self.get_delete_url_name), 11 ] 12 13 patterns.extend(self.extra_urls()) 14 return patterns
其中,各视图函数:

1 def list_view(self,request,*args,**kwargs): 2 3 ###################### 处理action ##################### 4 5 action_list = self.action_list 6 action_dict = {func.__name__:func.text for func in action_list} 7 8 if request.method == 'POST': 9 func_name = request.POST.get('action') 10 if func_name and func_name in action_dict: #逻辑优化,防止被 方法乱入 11 func = getattr(self,func_name) 12 func(request) 13 14 15 ###################### 1.搜索(有值才会显示搜索框) ##################### 16 search_list = self.get_search_list() 17 search_value = request.GET.get('q','') 18 19 from django.db.models import Q 20 conn = Q() 21 conn.connector = 'OR' 22 23 if search_value: 24 #Q,用于构造复杂的ORM查询条件 25 for item in search_list: 26 conn.children.append((item,search_value)) 27 28 ######################### 2.获取排序 ############################### 29 order_list = self.get_order_list() 30 31 #组合搜索条件字典 32 search_dict = self.get_search_group_condition(request) 33 34 #自定义方法筛选后的结果 35 queryset = self.get_queryset(**kwargs) 36 # print(queryset) 37 queryset = queryset.filter(conn).filter(**search_dict).all().order_by(*order_list) 38 39 ###################### 3.处理分页(使用组件) ####################### 40 all_count = queryset.count() 41 query_params = request.GET.copy() # ?=page=1&name='李四' 42 query_params._mutable = True #query_params['page']默认是不可以修改的 43 44 pager = Pagination( 45 current_page=request.GET.get('page'), 46 all_count=all_count, 47 base_url=request.path_info, 48 query_params=query_params, 49 per_page=self.per_page_count, 50 ) 51 52 ###################### 4.处理表格 ############################## 53 list_display = self.get_list_display() 54 # 4.1处理表头 55 header_list = [] 56 if list_display: 57 for multi_key in list_display: 58 if isinstance(multi_key,FunctionType): #判断 传入值是否为函数 59 verbose_name = multi_key(self,obj=None,is_header=True) 60 else: 61 verbose_name = self.model_class._meta.get_field(multi_key).verbose_name 62 header_list.append(verbose_name) 63 else: 64 header_list.append(self.model_class._meta.model_name) 65 66 # 4.2处理表的内容 67 data_list = queryset[pager.start:pager.end] 68 69 body_list = [] 70 for row in data_list: #row 是UserInfo object (1) 71 row_list = [] 72 73 if list_display: 74 for multi_key in list_display: 75 if isinstance(multi_key,FunctionType): 76 row_list.append(multi_key(self,row,is_header=False,*args,**kwargs)) 77 else: 78 row_list.append(getattr(row,multi_key)) #获取UserInfo object (1)的属性 79 else: 80 row_list.append(row) 81 82 body_list.append(row_list) 83 84 ###################### 5.处理添加按钮 ############################## 85 add_btn = self.get_add_btn(**kwargs) #是一个URL 86 87 ###################### 6.处理组合搜索 ############################## 88 search_group_row_list = [] 89 search_group = self.get_search_group() # ['gender', 'depart'] 90 for keyword_object in search_group: #keyword是一个Option类实例对象 91 row = keyword_object.get_queryset_or_tuple(self.model_class,request,*args,**kwargs) 92 #返回的是一个SearchGroupRow对象,且可迭代 93 search_group_row_list.append(row) 94 95 96 return render(request, 97 self.list_template or 'list.html', 98 {'body_list':body_list, 99 'header_list':header_list, 100 'pager':pager, 101 'add_btn':add_btn, 102 'search_list':search_list, 103 'search_value':search_value, 104 'action_dict':action_dict, 105 'search_group_row_list':search_group_row_list})

1 def add_view(self,request,*args,**kwargs): 2 """ 3 添加视图 4 :param request: 5 :return: 6 """ 7 8 model_form = self.get_model_form() 9 if request.method == 'GET': 10 form = model_form 11 return render(request, 'change.html', {'form': form}) 12 13 form = model_form(data=request.POST) 14 if form.is_valid(): 15 response = self.save(request,form,False,*args,**kwargs) 16 return response or redirect(self.reverse_list_url(**kwargs)) 17 return render(request,'change.html',{'form':form})

1 def change_view(self,request,pk,*args,**kwargs): 2 """ 3 编辑视图 4 :param request: 5 :param pk: 6 :return: 7 """ 8 checked_obj = self.get_change_object(request, pk, *args, **kwargs) 9 10 if not checked_obj: 11 return render(request,'rbacerror.html') 12 13 model_form = self.get_model_form() 14 if request.method == 'GET': 15 form = model_form(instance=checked_obj) 16 return render(request, 'change.html', {'form': form}) 17 18 form = model_form(data=request.POST,instance=checked_obj) 19 if form.is_valid(): 20 response = self.save(request, form, True, *args, **kwargs) 21 return response or redirect(self.reverse_list_url(**kwargs)) 22 return render(request, 'change.html', {'form': form})

1 def delete_view(self,request,pk,*args,**kwargs): 2 """ 3 删除视图 4 :param request: 5 :param pk: 6 :return: 7 """ 8 checked_obj = self.model_class.objects.filter(pk=pk).first() 9 if not checked_obj: 10 return render(request,'rbacerror.html',) 11 12 list_url = self.reverse_list_url(**kwargs) 13 if request.method == 'GET': 14 return render(request,'delete.html',{'list_url':list_url}) 15 16 response = self.delete_object(request, pk, *args, **kwargs) 17 return response or redirect(list_url)
以及生成各URL的别名:
1 def extra_urls(self): 2 return [] 3 4 def get_url_name(self,param): 5 """ 6 返回别名(所有别名最后在这里处理) 7 :param param: 8 :return: 9 """ 10 app_name = self.model_class._meta.app_label 11 model_name = self.model_class._meta.model_name 12 if self.prev: 13 return '%s_%s_%s_%s' %(app_name,model_name,self.prev,param) #Web_customer_public_list 14 return '%s_%s_%s' %(app_name,model_name,param) 15 16 @property 17 def get_list_url_name(self): 18 """ 19 获取列表页面URL的name 20 :return: 21 """ 22 return self.get_url_name('list') 23 24 @property 25 def get_add_url_name(self): 26 """ 27 获取列表页面URL的name 28 :return: 29 """ 30 return self.get_url_name('add') 31 32 @property 33 def get_change_url_name(self): 34 """ 35 获取列表页面URL的name 36 :return: 37 """ 38 return self.get_url_name('change') 39 40 @property 41 def get_delete_url_name(self): 42 """ 43 获取列表页面URL的name 44 :return: 45 """ 46 return self.get_url_name('delete')