一、先看下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】的更多相关文章

  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. eclipse 代码检查插件使用

    本文是按照以下这篇文章进行实践而来. 因此请参照:   https://www.ibm.com/developerworks/cn/java/j-ap01117/index.html 五种插件: Ch ...

  2. ElasticSearch match, match_phrase, term区别

    1.term结构化字段查询,匹配一个值,且输入的值不会被分词器分词. 比如查询条件是: { "query":{ "term":{ "foo" ...

  3. TCP连接异常断开检测(转)

    TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...

  4. NAT与FULL NAT的区别

    LVS 当前应用主要采用 DR 和 NAT 模式,但这 2 种模式要求 RealServer 和 LVS在同一个 vlan中,导致部署成本过高:TUNNEL 模式虽然可以跨 vlan,但RealSer ...

  5. Shell条件表达式

    Shell编程中经常需要判断文件状态.字符串是否相等以及两个数值大小等情况,基于这些比较结果再做执行相关操作.本文主要讲述文件状态.字符串.数值大小的判断比较方法. 文件状态判断 文件状态的判断通常使 ...

  6. ajax分页代码

    <meta charset="utf-8"><?php//连接数据库$link = mysqli_connect('127.0.0.1','root','root ...

  7. windows下配置mysql环境变量 - 使用cmd访问mysql(图)

    window7为例,右击“计算机” - 单击“属性” - 单击“高级系统设置” - 单击“环境变量”,剩下看图: <图1> 右下角"环境变量". <图2>选 ...

  8. 14.Java集合简述.md

    Java的集合类别,分为两类Collection和Map,Collenction包含了Set: •Set:无序,不可重复的集合 •List:有序,重复的集合 •Map:具有映射关系的集合 •Queue ...

  9. tkinter绑定鼠标滚轮滚动事件 canvas.bind("<MouseWheel>", processWheel) 失效

    其实,不同系统不一样,我的是Ubuntu 所以是<Button-4>   <Button-5> 见下: 来自:https://stackoverflow.com/questio ...

  10. 历届试题 对局匹配-(dp)

    问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起.如果两人分差 ...