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"] 

  

stark组件之搜索【模仿Django的admin】详解编程语言

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

stark组件之搜索【模仿Django的admin】详解编程语言

二、下面看下我们的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 

  

stark组件之搜索【模仿Django的admin】详解编程语言

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

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

  

 stark组件之搜索【模仿Django的admin】详解编程语言

 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) 

  

stark组件之搜索【模仿Django的admin】详解编程语言

 通过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 

  

stark组件之搜索【模仿Django的admin】详解编程语言

获取到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 
                                                }) 

  

重点是看这里

stark组件之搜索【模仿Django的admin】详解编程语言

 然后我们在看下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请求,这是我们不常用而已

stark组件之搜索【模仿Django的admin】详解编程语言

 7、页面效果如下

 stark组件之搜索【模仿Django的admin】详解编程语言

stark组件之搜索【模仿Django的admin】详解编程语言

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/20776.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论