Django 之stark组件点击筛选功能

 

 

 

 

一:用于筛选的类。在展示的试图函数中使用

#用于筛选的类。在展示的试图函数中使用
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})

 

 

 

 



posted on 2018-03-28 15:06  王大拿  阅读(228)  评论(0)    收藏  举报

导航