![]()
一:用于筛选的类。在展示的试图函数中使用
#用于筛选的类。在展示的试图函数中使用
class Filter_Field(object):
#初始化类属性,接收筛选字段的字段名称和字段的对象,
def __init__(self,filter_field_name,filter_field_obj):
self.filter_field_name=filter_field_name
self.filter_field_obj=filter_field_obj
#用于返回字段的相关的所有对象
def get_data(self):
#当字段的属性是一对多或者多对多时,用此方法
if isinstance(self.filter_field_obj,ManyToManyField) or isinstance(self.filter_field_obj,ForeignKey):
return self.filter_field_obj.rel.to.objects.all()
#当字段中有choices属性时用此方法
if self.filter_field_obj.choices:
return self.filter_field_obj.choices
else:
pass
二:定义另一个类
#定义一个类来处理每一个字段对应的所有的对象的属性,生成a标签
# 如 <QuerySet [<Publish: 深圳>, <Publish: 深圳1234大钟寺>, <Publish: 123有几分>, <Publish: 顶顶顶>]>
# <QuerySet [<Author: 金庸>, <Author: 金刚>, <Author: jj>]>
#对这些数据进行处理得到类似于 <a href="?publishs=6">深圳</a> 这样的标签返回给页面就能够渲染了
class LinkTagsGen(object):
#初始化类的属性,接收三个参数
def __init__(self,data,filter_field,request):
self.data=data
self.filter_field=filter_field
self.request=request
#定义一个 iter方法
def __iter__(self):
import copy
#将请request.GET的返回对象进行深拷贝 QueryDict
params =copy.deepcopy(self.request.GET)
#属性设置为可以改变类型的
params._mutabl=True
#获取当前的id值,没有的话设为0
current_id = int(self.request.GET.get(self.filter_field.filter_field_name,0))
#设置一个全部按钮 当params中有此字段对应的键值对时 如当前是publishs这个字段
if params.get(self.filter_field.filter_field_name): #如是 {"publishs":1,"authots":2}
#将params中的键值对删除,这是点击全部按钮的功能 删除这个字段的值 {"authots":2}
del(params[self.filter_field.filter_field_name])
#得到一当前的url 由 publishs=1&authors=2 的这中变成只包含?authors=2
_url = '%s?%s' % (self.request.path_info, params.urlencode())
yield (mark_safe('<a href="%s">%s</a>' % (_url,'全部 ')))
else:
#如果没有这个字段 则表示当前选中的是全部按钮 给他加上一个自己在前端定义的active 让文字显示红色表示选中
yield (mark_safe('<a class="active" href="">%s</a>' % ('全部 ')))
#对数据进行设置
for item in self.data:
# print('item------------------------',item)
#当字段为一对多或多对多字段时
if isinstance(self.filter_field.filter_field_obj,ManyToManyField) or isinstance(self.filter_field.filter_field_obj,ForeignKey):
# print('self.params.1111111111()--------------------', params.urlencode())
params[self.filter_field.filter_field_name]=item.pk
_url='%s?%s'%(self.request.path_info,params.urlencode())
#如果此标签为被选中的 则给他加一个active类,表示选中。
if item.pk==current_id:
a = mark_safe('<a class="active" href="%s">%s</a>' % (_url, item))
else:
a = mark_safe('<a href="%s">%s</a>' % (_url, item))
yield a
#当字段中有choices属性时 用此方法
elif self.filter_field.filter_field_obj.choices:
# 因为上边给params设置了可以修改的属性,所以可以在QueryDict字典中添加内容
#比如用户选择了authors=2的这个属性,那么 在每个a标签的href中都添加了这个字段, 即记录了上次的选则,
#可以通过此方法完成多条件筛选 如果上次选择过 authors
# 这次再选择的话就会对数据进行更新 将新内容更新进去
params[self.filter_field.filter_field_name] = item[0]
# print('item[0]-------------',item[0])
_url = '%s?%s' % (self.request.path_info,params.urlencode())
if item[0]==current_id:
a=mark_safe('<a class="active" href="%s">%s</a>'%(_url,item[1]))
# print('self.params.2222222()--------------------',params.urlencode())
else:
a = mark_safe('<a href="%s">%s</a>' % (_url, item[1]))
yield a
三:在显示类中定义一个方法 用于显示点击筛选的内容
class ShowList(object):
def __init__(self,config,request,queryset):
self.request = request
self.config = config
self.queryset = queryset
self.list_filter=self.config.list_filter
#处理筛选功能 动态显示可点击的筛选按钮
def get_filter_link_tags(self):
list1 = []
import copy
#获取用户请求的请求头中的信息,进行深度拷贝
params=copy.deepcopy(self.request.GET)
# print('params=====================',params)
#将_mutable的属性设置为True,即为可以改变的属性
params._mutable=True
for filter_field_name in self.list_filter:
filter_field_obj=self.config.model._meta.get_field(filter_field_name)
filter_field=Filter_Field(filter_field_name,filter_field_obj)
# def inner(filter_field):
filter_field_list=filter_field.get_data()
#实例化一个对象
# print('filter_field_list----',filter_field_list)
val=LinkTagsGen(filter_field_list,filter_field,self.request)
#用yield方法 在循环中将数据取出,迭代器,节省内存空间
yield val.__iter__()
################################################################################
#双层For循环来处理数据 此方法有弊端,就是数据太多的话会占用太多内存
# list2 = []
# for field in filter_field_list:
#
# if isinstance(filter_field.filter_field_obj,ForeignKey) or isinstance(filter_field.filter_field_obj,ManyToManyField):
# #因为上边给params设置了可以修改的属性,所以可以在QueryDict字典中添加内容
# #比如用户选择了authors=2的这个属性,那么 在每个a标签的href中都添加了这个字段, 即记录了上次的选则,
# # 可以通过此方法完成多条件筛选
# params[filter_field.filter_field_name]=field.pk #正是因为设置了_mutable的属性 才可以给 params添加键值对等修改操作
#
# list2.append(mark_safe('<a href="?%s">%s</a>'%(params.urlencode(),field)))
#
# elif filter_field.filter_field_obj.choices:
# params[filter_field.filter_field_name]=field[0]
# list2.append(mark_safe('<a href="?%s">%s</a>' % (params.urlencode(), field[1])))
# else:
# continue
#
# list1.append(list2)
# print('list1----------------------',list1)
# return list1
#
#处理筛选后数据的处理和返回
四:在展示的视图函数中,实例化方法三中的类,将获取数据
#显示页面
def show_List(self,request):
#当是提交事件时,获取了批量操作的名称,数据,完成批量操作
if request.method=='POST':
#从form 表单回传的数据中取出action
action=request.POST.get('action')
#从回传的数据中取出 选中的内容的 里边放数据是这种类型的 ['1','3','4']
queryset = request.POST.getlist('select_action')
#利用发射取出MOdelStark类中的action方法,
func=getattr(self,action)
#执行方法
ret=func(queryset)
self.request=request
#获取将要模糊搜索的内容
search_condition=self.get_search_condition()
# print(search_condition)
#获取用户点击筛选的内容
filter_condition=self.get_filter_condition()
# print('search_condition+++++++++++++++++++++++++++++++++++++++++++',search_condition)
data_list=self.model.objects.filter(search_condition).filter(filter_condition)
# data_list=self.model.objects.filter(publishs=1)
# print('data_list11111111111111111',data_list)
# data_list=data_list.filter(publishs=6)
# print('data_list222222222222222222222',data_list)
# filter_condition=self.get_filter_condition()
# # print('search_condition+++++++++++++++++++++++++++++++++++++++++++',search_condition)
# data_list=self.model.objects.filter(filter_condition)
# data_list=self.model.objects.filter()
queryset=data_list
s1=ShowList(self,request,queryset)
new_data_list=s1.get_body()
title_list=s1.get_header()
add_url=s1.add_url()
filter_list=s1.get_filter_link_tags()
action_list=self.handle_action()
# print('get-------------------',request.GET)
# return render(request,'stark/showlist.html',{'new_data_list':new_data_list,'list_display':new_list_display,'title_list':title_list,'add_url':add_url,"page_html":page_html})
return render(request,'stark/showlist.html',{'new_data_list':new_data_list,'title_list':title_list,'add_url':add_url,'action_list':action_list,'filter_list':filter_list})