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

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

  1. class testbook(admin.ModelAdmin):
  2.  
  3. # 第一步,定义一个函数,必须要接受三个参数
  4. def test_action(self,request,queryset):
  5. """
  6.  
  7. :param request:
  8. :param queryset:这个就是需要批量操作的queryset对象
  9. :return:
  10. """
  11. print(queryset)
  12.  
  13. # 第二步,为这个函数对象赋值一个新的属性
  14. test_action.short_description = "测试批量操作的函数"
  15.  
  16. # 第三步,将函数对象添加到actions这个列表中
  17. actions = [test_action]
  18.  
  19. list_filter = ["auther","publist"]
  20.  
  21. search_fields = ["auther","title"]

  

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

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

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

  1. class bookclass(stark.Starkclass):
  2.  
  3. list_display = ["id","title","price","auther","publish"]
  4. list_display_links = ["id","price","auther"]
  5. search_fields = ["title","price"]
  6. def test_action(self,request,queryset):
  7. print(queryset,)
  8.  
  9. actions = [test_action]
  10. # test_action.__name__ = "测试批量操作的函数"
  11. test_action.short_description = "测试批量操作的函数"
  12.  
  13. modelformclass = mybookmodelform

  

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

  1. class Starkclass(object):
  2. list_display = ['__str__']
  3. list_display_links = []
  4. search_fields = []
  5. modelformclass = None
  6. actions = []
  7.  
  8. list_filter = []

  

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

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

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

  1. def list_url(self,request):
  2. import importlib
  3. if request.method == "POST":
  4. func = request.POST.get("func")
  5. action_list = request.POST.getlist("selectpk")
  6. action_func = getattr(self,func)
  7. queryset = self.model.objects.filter(id__in=action_list)
  8. action_func(request,queryset)
  9.  
  10. new_list = self.create_new_display()
  11. q_obj = self.get_search(request)
  12. q_filter_obj = self.get_filter(request)
  13.  
  14. if q_obj and q_filter_obj:
  15. new_data_list = self.model.objects.all().filter(q_obj).filter(q_filter_obj)
  16. elif q_obj and not q_filter_obj:
  17. new_data_list = self.model.objects.all().filter(q_obj)
  18. elif not q_obj and q_filter_obj:
  19. new_data_list = self.model.objects.all().filter(q_filter_obj)
  20. else:
  21. new_data_list = self.model.objects.all()
  22.  
  23. showlist = Showlist(self, request, new_list,new_data_list)

  

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

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

  1. def get_search(self,request):
  2. from django.db.models import Q
  3.  
  4. search_str = request.GET.get("search", None)
  5.  
  6. if search_str:
  7. if self.search_fields:
  8. q_obj = Q()
  9. q_obj.connector = "or"
  10.  
  11. for field in self.search_fields:
  12. q_obj.children.append((field + "__icontains", search_str))
  13. return q_obj
  14. else:
  15. return None
  16. else:
  17. return None

  

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

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

  1. def list_url(self,request):
  2. import importlib
  3. if request.method == "POST":
  4. func = request.POST.get("func")
  5. action_list = request.POST.getlist("selectpk")
  6. action_func = getattr(self,func)
  7. queryset = self.model.objects.filter(id__in=action_list)
  8. action_func(request,queryset)
  9.  
  10. new_list = self.create_new_display()
  11. q_obj = self.get_search(request)
  12. q_filter_obj = self.get_filter(request)
  13.  
  14. if q_obj and q_filter_obj:
  15. new_data_list = self.model.objects.all().filter(q_obj).filter(q_filter_obj)
  16. elif q_obj and not q_filter_obj:
  17. new_data_list = self.model.objects.all().filter(q_obj)
  18. elif not q_obj and q_filter_obj:
  19. new_data_list = self.model.objects.all().filter(q_filter_obj)
  20. else:
  21. new_data_list = self.model.objects.all()
  22.  
  23. showlist = Showlist(self, request, new_list,new_data_list)
  24. title_list = showlist.get_header()
  25. data_list = showlist.get_body()
  26. page_str = showlist.get_page()
  27. action_str = showlist.get_actions()
  28. get_filter = showlist.get_filter_link_tag()
  29.  
  30. 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,
  31. "get_filter":get_filter
  32. })

  

重点是看这里

然后我们在看下showlist的类

  1. class Showlist(object):
  2. def __init__(self,config,request,new_list,new_data_list):
  3. self.config = config
  4. self.request = request
  5. self.new_list = new_list
  6. self.new_data_list = new_data_list
  7.  
  8. # 分页显示
  9. count = self.new_data_list.count()
  10. current_page = int(request.GET.get("p",1))
  11. per_page_num = 3
  12. base_url = request.path_info
  13. parms = request.GET
  14. self.page_str = page.page_helper(count=count,current_page=current_page,per_page_num=per_page_num,base_url=base_url,parms=parms)

  

  1. def get_body(self):
  2. from django.db.models import Q
  3. new_list = self.new_list
  4.  
  5. data_list_obj = self.new_data_list[self.page_str.db_start() - 1:self.page_str.db_end() - 1]
  6. data_list = []
  7. for obj in data_list_obj:
  8. temp_list = []
  9. for i in new_list:
  10. if not callable(i):
  11. if self.config.list_display_links:
  12.  
  13. if i in self.config.list_display_links:
  14. # i_obj = obj._meta.get_field(i)
  15. # print(type(i_obj),"i_obj",i)
  16. from django.db.models.fields.related import ManyToManyField
  17. i_obj = obj._meta.get_field(i)
  18. if isinstance(i_obj,(ManyToManyField,)):
  19. many = getattr(obj, i)
  20. many_query_set = many.all()
  21. temp = ""
  22. for o in many_query_set:
  23. temp = temp + str(o) + "&"
  24. temp = temp.rstrip("&")
  25. else:
  26. temp = getattr(obj,i)
  27. app_name = obj._meta.app_label
  28. model_name = obj._meta.model_name
  29. edit_path = "/stark/{app}/{model}/edit/{eid}".format(app=app_name, model=model_name, eid=obj.id)
  30. temp = mark_safe("<a href='{path}'>{link}</a>".format(link=temp,path=edit_path))
  31. else:
  32. from django.db.models.fields.related import ManyToManyField
  33. i_obj = obj._meta.get_field(i)
  34. if isinstance(i_obj,(ManyToManyField,)):
  35. many = getattr(obj, i)
  36. many_query_set = many.all()
  37. temp = ""
  38. for o in many_query_set:
  39. temp = temp + str(o) + "&"
  40. temp = temp.rstrip("&")
  41. else:
  42. temp = getattr(obj, i)
  43. else:
  44. temp = getattr(obj,i)
  45. else:
  46. temp = i(self,obj)
  47. temp_list.append(temp)
  48. data_list.append(temp_list)
  49. return data_list

  

返回过滤后的数据

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

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

  

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

7、页面效果如下

stark组件之搜索【模仿Django的admin】的更多相关文章

  1. stark组件之路由分发【模仿Django的admin】

    一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...

  2. stark组件之pop操作【模仿Django的admin】

    一.先看下什么django的admin的pop到底是个什么东西 其实就是这么一个东西, a.在添加页面,在一对多和多对多的项后加了一个+号 b.点击这个加号,会弹出对应的添加 页面,在新的添加 c.添 ...

  3. stark组件之批量操作【模仿Django的admin】

    一.先看下django的admin是如何实现批量操作 首先在配置类中定义一个函数 然后我们为这个函数对象设置一个属性,这个属性主要用来显示在select标签中显示的文本内容 最后把函数对象放到一个ac ...

  4. stark组件之启动【模仿Django的admin】

    首先需要在settings注册app INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib ...

  5. stark组件之注册【模仿Django的admin】

    一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...

  6. stark组件之过滤操作【模仿Django的admin】

    一.先看下django的admin是如何实现过滤操作 首先在配置类中顶一个list_filter的列表,把要过滤的字段作为元素写i进去就可以了 class testbook(admin.ModelAd ...

  7. stark组件之分页【模仿Django的admin】

    我们的stark组件用的我们的分页组件,没有重新写 下面直接看下分页的代码 class page_helper(): def __init__(self, count, current_page, p ...

  8. 模拟admin组件自己开发stark组件之搜索和批量操作

    搜索相关,搜索的本质就是从数据库查询出来的数据过滤 用户自定义给出过滤条件joker.py list_display = ('id','title','price',) show_add_btn = ...

  9. admin源码解析以及仿照admin设计stark组件

    ---恢复内容开始--- admin源码解析 一 启动:每个APP下的apps.py文件中. 首先执行每个APP下的admin.py 文件. def autodiscover(): autodisco ...

随机推荐

  1. hive理论

    join操作: 这个 group by count()操作: 数据倾斜: 操作• Join on a.id=b.id• Group by• Count Distinct count(groupby)• ...

  2. js模板引擎初级

    模板引擎:模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的html文档. 模板引擎的实现方式有 ...

  3. 修改 计算机名后,修改SQLserver 注册服务器对象的名称,及登陆名

    select @@ServerName --查看当前所有数据库服务器名称select * from Sys.SysServers --修改数据库服务器名称sp_dropserver 'old_serv ...

  4. (Java)怎么去掉字符串数组中重复的值?

    String fdbs = "WXB,WXA,FDA,WXB"; String[] str = fdbs.split(","); Set set = new H ...

  5. Haskell语言学习笔记(85)Async

    安装 async $ cabal install async async-2.2.1 installed async / wait / concurrently async :: IO a -> ...

  6. springmvc简单教程

    IDEA建立Spring MVC Hello World 详细入门教程(转自)   引子,其实从.NET转Java已经有几个月时间了,项目也做了不少,但是很多配置都是根据公司模板或者网上教程比忽略画瓢 ...

  7. gitlab jenkins 自动构建

    工作中有这样一种需求: 每次提交代码之后,都自动执行 单元测试脚本,进行单元测试 jenkins监听项目的某个分支,设置运行脚本,设置一个url作为回调 利用gitlab的钩子,在每次有提交之后,触发 ...

  8. JS代码注释

    1.css和js都可以使用/**/进行注释 2.html使用<!---->注释 3.单行js代码可以使用//进行注释 <!DOCTYPE html> <html lang ...

  9. eclipse调试快捷键

    Eclipse中有如下一些和运行调试相关的快捷键. 1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点.    2. [F11]:调试最后一次执行的程序.    3. [Ctrl+F ...

  10. unity 2048Game

    将游戏分为四个脚本,将数据和界面分开,这是开发模式常用的类似于mvc模式,但由于我们只用一个二位数组就可以保存数据,所以讲m省略 GameControllor 控制游戏数据的脚本, using Uni ...