搜索是一個復雜的功能,但對於一些簡單的搜索任務,可以使用 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 }