到现在为止,我们已经为list视图添加了分页、显示表头、显示数据内容,添加制定按钮、选择器等功能。结果就是list函数比较臃肿,下面我们就要考虑一下怎么把list视图函数进行一下封装。
我们看一下现有的ConfXadmin类里的部分函数
因为list函数调用的多个函数,而这些函数之间还有可能是互相牵扯的,所以这里就不太适合按照函数的形式来封装,这里就应该按照类的形式来封装
显示类的构造
就现有的视图目的来说,list视图主要有两个部分:字段标题的显示和数据内容的显示,所以我们把标题和内容分别封装到两个方法里
class List_View(): def __init__(self): pass def get_title(self): pass def get_data(self): pass
下面要做的就是把前面list_view里的部分函数直接贴过来
1 class List_View(): 2 def __init__(self,conf_obj,data_list,request): 3 self.conf_obj = conf_obj 4 self.data_list = data_list 5 self.request = request 6 7 #标题显示 8 def get_title(self): 9 10 field_title_list = [] 11 for field in self.conf_obj.get_display_field(): 12 if callable(field): 13 field_title = field(self.conf_obj,get_title=True) 14 else: 15 16 if field == '__str__': 17 field_title = self.conf_obj.model_name.upper() 18 else: 19 field_title = self.conf_obj.model._meta.get_field(field).verbose_name 20 21 field_title_list.append(field_title) 22 23 return field_title_list 24 25 #内容显示 26 def get_data(self): 27 show_data_list = [] 28 29 #分页 30 page = int(self.request.GET.get('page',1)) 31 32 data_totle = self.data_list.count() 33 page_cut = Page_Cut(page=page, 34 url_prefix=self.conf_obj.get_list_url(), 35 param=self.request.GET, 36 data_totle=data_totle) 37 38 cut_html = page_cut.page_html 39 40 cut_data = self.data_list[page_cut.ID_start:page_cut.ID_end] 41 42 for model_obj in cut_data: 43 temp = [] 44 45 for field in self.conf_obj.get_display_field(): 46 if callable(field): 47 val = field(self.conf_obj,model_obj) 48 else: 49 val = getattr(model_obj,field) 50 temp.append(val) 51 52 show_data_list.append(temp) 53 54 return show_data_list,cut_html 55
这里要注意的地方就是贴代码的时候,self在贴到List_View类里以后随着调用方发生改变,self代指的对象也就不一样了。注意在原函数中,原先的self是ConfXadmin类里的调用的,所以我们需要来List_Vist在实例化的时候把这个self传过去
1 def list_view(self,request): 2 new_data_url = self.get_add_url() 3 all_data = self.model.objects.all() 4 5 view_obj = List_View(self,all_data,request) 6 7 8 field_title_list = view_obj.get_title() 9 10 show_data_list,cut_html = view_obj.get_data() 11 12 return render(request,'list.html',locals())
注意第5行里的实例化的过程,这个self代表的是什么。
而在后期我们需要修改视图的时候,只要修改那个类就行啦。
模板的渲染
由于我们只是修改了list_view()视图,然后在render的时候通过locals()传递的模板变量。所以list.html文件我们是不用修改的。
其实 还有一种渲染模板的方法,就是直接把实例化的对象传过去,然后在模板中直接调用
{{view_obj.get_title}}
这样就拿到了视图中的view_obj对象。然后可以通过for循环生成需要的html代码。