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、页面效果如下
stark组件之搜索【模仿Django的admin】的更多相关文章
- stark组件之路由分发【模仿Django的admin】
一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...
- stark组件之pop操作【模仿Django的admin】
一.先看下什么django的admin的pop到底是个什么东西 其实就是这么一个东西, a.在添加页面,在一对多和多对多的项后加了一个+号 b.点击这个加号,会弹出对应的添加 页面,在新的添加 c.添 ...
- stark组件之批量操作【模仿Django的admin】
一.先看下django的admin是如何实现批量操作 首先在配置类中定义一个函数 然后我们为这个函数对象设置一个属性,这个属性主要用来显示在select标签中显示的文本内容 最后把函数对象放到一个ac ...
- stark组件之启动【模仿Django的admin】
首先需要在settings注册app INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib ...
- stark组件之注册【模仿Django的admin】
一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...
- stark组件之过滤操作【模仿Django的admin】
一.先看下django的admin是如何实现过滤操作 首先在配置类中顶一个list_filter的列表,把要过滤的字段作为元素写i进去就可以了 class testbook(admin.ModelAd ...
- stark组件之分页【模仿Django的admin】
我们的stark组件用的我们的分页组件,没有重新写 下面直接看下分页的代码 class page_helper(): def __init__(self, count, current_page, p ...
- 模拟admin组件自己开发stark组件之搜索和批量操作
搜索相关,搜索的本质就是从数据库查询出来的数据过滤 用户自定义给出过滤条件joker.py list_display = ('id','title','price',) show_add_btn = ...
- admin源码解析以及仿照admin设计stark组件
---恢复内容开始--- admin源码解析 一 启动:每个APP下的apps.py文件中. 首先执行每个APP下的admin.py 文件. def autodiscover(): autodisco ...
随机推荐
- hive理论
join操作: 这个 group by count()操作: 数据倾斜: 操作• Join on a.id=b.id• Group by• Count Distinct count(groupby)• ...
- js模板引擎初级
模板引擎:模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的html文档. 模板引擎的实现方式有 ...
- 修改 计算机名后,修改SQLserver 注册服务器对象的名称,及登陆名
select @@ServerName --查看当前所有数据库服务器名称select * from Sys.SysServers --修改数据库服务器名称sp_dropserver 'old_serv ...
- (Java)怎么去掉字符串数组中重复的值?
String fdbs = "WXB,WXA,FDA,WXB"; String[] str = fdbs.split(","); Set set = new H ...
- Haskell语言学习笔记(85)Async
安装 async $ cabal install async async-2.2.1 installed async / wait / concurrently async :: IO a -> ...
- springmvc简单教程
IDEA建立Spring MVC Hello World 详细入门教程(转自) 引子,其实从.NET转Java已经有几个月时间了,项目也做了不少,但是很多配置都是根据公司模板或者网上教程比忽略画瓢 ...
- gitlab jenkins 自动构建
工作中有这样一种需求: 每次提交代码之后,都自动执行 单元测试脚本,进行单元测试 jenkins监听项目的某个分支,设置运行脚本,设置一个url作为回调 利用gitlab的钩子,在每次有提交之后,触发 ...
- JS代码注释
1.css和js都可以使用/**/进行注释 2.html使用<!---->注释 3.单行js代码可以使用//进行注释 <!DOCTYPE html> <html lang ...
- eclipse调试快捷键
Eclipse中有如下一些和运行调试相关的快捷键. 1. [Ctrl+Shift+B]:在当前行设置断点或取消设置的断点. 2. [F11]:调试最后一次执行的程序. 3. [Ctrl+F ...
- unity 2048Game
将游戏分为四个脚本,将数据和界面分开,这是开发模式常用的类似于mvc模式,但由于我们只用一个二位数组就可以保存数据,所以讲m省略 GameControllor 控制游戏数据的脚本, using Uni ...