django 实现简单的检索功能
搜索是一个复杂的功能,但对于一些简单的搜索任务,可以使用 django model 层提供的一些内置方法来完成。
使用 django 模型管理器的 Q, filter 方法, icontains 查询表达式来实现一个简单的搜索功能。
以商城为例,每个商品都会有名称和详细商品介绍这两个部分。当用户输入某个关键词进行搜索后,我们希望显示商品的列表中含有关于搜索关键词的全部商品。
整个搜索的过程如下:
用户在搜索框中输入搜索关键词,假设为"外套",点击搜索按钮提交输入的结果到服务器
服务器接收到用户输入的搜索关键词"外套"后去数据库查找商品名中含有该关键词的全部商品
服务器将查询结果返回给用户
用户在搜索框输入搜索关键词,因此我们要在商城上为用户提供一个搜索框
这里我们使用heyui控件中的搜索:
<Search v-model="text" @search="search" placeholder="请输入关键词搜索"></Search> // 检索逻辑 search() { if (this.text == '') { this.$Message('搜索内容不能为空'); return false } //跳到搜索页面 组件间相互传值 this.$router.push({ path: '/search', query: {text: this.text} }) },
用户输入了搜索关键词并点击了Enter键后,数据就被发送给了 django 后台服务器。
django中:
1 # 商品搜索 2 class GoodsSearch(APIView): 3 def get(self, request): 4 title = request.GET.get('title', None) 5 # 使用 icontains 6 # goodslist = models.Goods.objects.filter(name__icontains=title) 7 # 使用 Q 多条件查询 8 goodslist = models.Goods.objects.filter(Q(name__icontains=title) | Q(desc__icontains=title)) 9 10 # 序列化 11 goodslist_ser = myser.GoodsSer(goodslist, many=True) 12 return Response(goodslist_ser.data)
Django filter 中用 contains 和 icontains 区别:
filter(name__contains="title") filter(name__icontains="title")
contains 精确大小写 icontains ( i: ingore 忽略 )忽略大小写
Django 多条件查询 Q
from django.db.models import Q goodslist = models.Goods.objects.filter(Q(name__icontains=title) | Q(desc__icontains=title))
| ( 管道 ) 代表 or ( 或者 ) , & 代表 并且
查询商品名和商品描述中含有该关键词的商品的信息
翻译成sql语句:
select * from goods where (name like ‘%title%’ or desc like ‘%title%’) and (parms like ‘%title%’)
记得配置路由 path(‘goodssearch/’, GoodsSearch.as_view()), # 商品检索
接下来就是搜索结果页面,显示符合搜索条件的商品列表。
1 <ul> 2 <li v-for="i in datalist">{{i.name}}</li> 3 </ul> 4 5 export default { 6 data() { 7 return { 8 //检索结果 9 datalist: [], 10 } 11 }, 12 13 mounted: function () { 14 // 接收关键字 15 var text = this.$route.query.text; 16 //进入页面立刻获取用户信息 17 //发送异步请求 18 this.axios.get('http://localhost:8000/goodssearch/', 19 {params: { 20 title:text 21 } 22 }).then((res) => { 23 console.log(res); 24 // 赋值操作 25 this.datalist=res.data 26 if (this.datalist.length == 0) { 27 this.$Message('暂时没有您要的产品') 28 } 29 }) 30 }
这个时候我们就完成了一个简单的检索功能。
但实际上你会发现 在搜索结果页面内无法进行再次检索
这个时候我们就要用到监听属性,在搜索结果页面内加入监听属性 避免只能搜索一次
1 //监听属性: 2 watch: { 3 $route(to, form) { 4 this.$router.go(0); 5 } 6 }