• stark组件之搜索【模仿Django的admin】


    一、先看下django的admin是如何做搜索功能的

    配置一个search_fields的列表就可以实现搜索的功能

    class testbook(admin.ModelAdmin):
    
        # 第一步,定义一个函数,必须要接受三个参数
        def test_action(self,request,queryset):
            """
    
            :param request:
            :param queryset:这个就是需要批量操作的queryset对象
            :return:
            """
            print(queryset)
    
        # 第二步,为这个函数对象赋值一个新的属性
        test_action.short_description = "测试批量操作的函数"
    
    
        # 第三步,将函数对象添加到actions这个列表中
        actions = [test_action]
    
        list_filter = ["auther","publist"]
    
        search_fields = ["auther","title"]
    

      

     看下页面的效果,这里就可以通过auther或者title进行搜索了

    二、下面看下我们的stark组件是如何做搜索的

    1、首先我们也在自己的配置类里定义一个search_field的搜索字段

    class bookclass(stark.Starkclass):
    
        list_display = ["id","title","price","auther","publish"]
        list_display_links = ["id","price","auther"]
        search_fields = ["title","price"]
        def test_action(self,request,queryset):
            print(queryset,)
    
        actions = [test_action]
        # test_action.__name__ = "测试批量操作的函数"
        test_action.short_description = "测试批量操作的函数"
    
    
        modelformclass = mybookmodelform
    

      

    2、同样,我们还需要在父类中定义一个search_field字段,为了防止客户未定义search_field字段和报错

    class Starkclass(object):
        list_display = ['__str__']
        list_display_links = []
        search_fields = []
        modelformclass = None
        actions = []
    
        list_filter = []
    

      

     

     3、然后我们看下具体的代码

    这里我们先简单的说一下思路,我们默认会显示所有的数据,那么,如果我们加了一个搜索的字段,那么我们中就加一个参数,这个参数的k就是search,v就是我们输入的值,

    这样后端拿到搜索的字段后,就可以使用Q查询做or的匹配,然后显示出过滤后的信息就可以了

        def list_url(self,request):
            import importlib
            if request.method == "POST":
                func = request.POST.get("func")
                action_list = request.POST.getlist("selectpk")
                action_func = getattr(self,func)
                queryset = self.model.objects.filter(id__in=action_list)
                action_func(request,queryset)
    
            new_list = self.create_new_display()
            q_obj = self.get_search(request)
            q_filter_obj = self.get_filter(request)
    
            if q_obj and q_filter_obj:
                new_data_list = self.model.objects.all().filter(q_obj).filter(q_filter_obj)
            elif q_obj and not q_filter_obj:
                new_data_list = self.model.objects.all().filter(q_obj)
            elif not q_obj and q_filter_obj:
                new_data_list = self.model.objects.all().filter(q_filter_obj)
            else:
                new_data_list = self.model.objects.all()
    
            showlist = Showlist(self, request, new_list,new_data_list)
    

      

     通过get_search函数去获取过滤的信息

    4、下面我们看下get_search函数的代码

        def get_search(self,request):
            from django.db.models import Q
    
            search_str = request.GET.get("search", None)
    
            if search_str:
                if self.search_fields:
                    q_obj = Q()
                    q_obj.connector = "or"
    
                    for field in self.search_fields:
                        q_obj.children.append((field + "__icontains", search_str))
                    return q_obj
                else:
                    return None
            else:
                return None
    

      

    获取到search的字段,然后做q查询,最终返回一个q对象

    5、list_url函数拿到返回的Q对象,然后做过滤,将过滤后的信息传递给showlist这个类,在来显示

        def list_url(self,request):
            import importlib
            if request.method == "POST":
                func = request.POST.get("func")
                action_list = request.POST.getlist("selectpk")
                action_func = getattr(self,func)
                queryset = self.model.objects.filter(id__in=action_list)
                action_func(request,queryset)
    
            new_list = self.create_new_display()
            q_obj = self.get_search(request)
            q_filter_obj = self.get_filter(request)
    
            if q_obj and q_filter_obj:
                new_data_list = self.model.objects.all().filter(q_obj).filter(q_filter_obj)
            elif q_obj and not q_filter_obj:
                new_data_list = self.model.objects.all().filter(q_obj)
            elif not q_obj and q_filter_obj:
                new_data_list = self.model.objects.all().filter(q_filter_obj)
            else:
                new_data_list = self.model.objects.all()
    
            showlist = Showlist(self, request, new_list,new_data_list)
            title_list = showlist.get_header()
            data_list = showlist.get_body()
            page_str = showlist.get_page()
            action_str = showlist.get_actions()
            get_filter = showlist.get_filter_link_tag()
    
            return render(request,"list_view.html",{"data_list":data_list,"title_list":title_list,"page_str":page_str,"search_fields":self.search_fields,"action_str":action_str,
                                                    "get_filter":get_filter
                                                    })
    

      

    重点是看这里

     然后我们在看下showlist的类

    class Showlist(object):
        def __init__(self,config,request,new_list,new_data_list):
            self.config = config
            self.request = request
            self.new_list = new_list
            self.new_data_list = new_data_list
    
            # 分页显示
            count = self.new_data_list.count()
            current_page = int(request.GET.get("p",1))
            per_page_num = 3
            base_url = request.path_info
            parms = request.GET
            self.page_str = page.page_helper(count=count,current_page=current_page,per_page_num=per_page_num,base_url=base_url,parms=parms)
    

      

        def get_body(self):
            from django.db.models import Q
            new_list = self.new_list
    
            data_list_obj = self.new_data_list[self.page_str.db_start() - 1:self.page_str.db_end() - 1]
            data_list = []
            for obj in data_list_obj:
                temp_list = []
                for i in new_list:
                    if not callable(i):
                        if self.config.list_display_links:
    
                            if i in self.config.list_display_links:
                                # i_obj = obj._meta.get_field(i)
                                # print(type(i_obj),"i_obj",i)
                                from django.db.models.fields.related import ManyToManyField
                                i_obj = obj._meta.get_field(i)
                                if isinstance(i_obj,(ManyToManyField,)):
                                    many = getattr(obj, i)
                                    many_query_set = many.all()
                                    temp = ""
                                    for o in many_query_set:
                                        temp = temp + str(o) + "&"
                                    temp = temp.rstrip("&")
                                else:
                                    temp = getattr(obj,i)
                                app_name = obj._meta.app_label
                                model_name = obj._meta.model_name
                                edit_path = "/stark/{app}/{model}/edit/{eid}".format(app=app_name, model=model_name, eid=obj.id)
                                temp = mark_safe("<a href='{path}'>{link}</a>".format(link=temp,path=edit_path))
                            else:
                                from django.db.models.fields.related import ManyToManyField
                                i_obj = obj._meta.get_field(i)
                                if isinstance(i_obj,(ManyToManyField,)):
                                    many = getattr(obj, i)
                                    many_query_set = many.all()
                                    temp = ""
                                    for o in many_query_set:
                                        temp = temp + str(o) + "&"
                                    temp = temp.rstrip("&")
                                else:
                                    temp = getattr(obj, i)
                        else:
                            temp = getattr(obj,i)
                    else:
                        temp = i(self,obj)
                    temp_list.append(temp)
                data_list.append(temp_list)
            return data_list
    

      

    返回过滤后的数据

    6、最后我们看下页面的代码,如果有search_field字段,页面才显示,如果没有则不会显示

                {% if search_fields %}
                    <form class="pull-right" method="get">
                        <input type="text" name="search" placeholder="搜索"><input type="submit" value="搜索">
                    </form>
                {% endif %}
    

      

    这里我们用form表单发get请求,进行搜索,之间我们都是用form表单发送post请求,其实form表单也可以发get请求,这是我们不常用而已

     7、页面效果如下

     

  • 相关阅读:
    ZOJ 3876 May Day Holiday 蔡勒公式
    ZOJ 3870 Team Formation 贪心二进制
    ZOJ 3872 计算对答案的贡献
    Codeforces Round #324 (Div. 2)C. Marina and Vasya set
    Jquery前端分页插件pagination使用
    最简单的混合开发教程资料汇总
    最简单的混合开发教程资料汇总
    2018年各大互联网前端面试题二(滴滴打车)
    2018年各大互联网前端面试题二(滴滴打车)
    【福利】小程序开发资源干货汇总
  • 原文地址:https://www.cnblogs.com/bainianminguo/p/10134956.html
Copyright © 2020-2023  润新知