Django多模型搜索实现:类Yelp的三种业务搜索需求
实现Django商家搜索功能(类似Yelp)
不用外部搜索引擎完全没问题,咱们直接用Django ORM就能搞定这三种搜索场景,而且比用itertools.chain高效得多——毕竟ORM会帮你生成优化的SQL查询,而chain只是把多个查询结果合并,没法做后续的分页、排序这些操作。
先提个小细节:你的Business模型里city字段用了OneToOneField,这意味着一个城市只能关联一个商家,这显然和Yelp的实际场景不匹配(正常一个城市会有N多商家)。如果这是笔误,建议改成ForeignKey,下面的代码逻辑完全通用,改完后搜索结果也会更符合预期。
核心思路
通过接收前端的搜索参数(城市、分类),动态构建Business的查询集:
- 如果有分类参数,就过滤出该分类的商家
- 如果有城市参数,就过滤出该城市的商家
- 两个参数都填的话,就同时过滤,正好对应你要的三种搜索场景
具体代码实现
1. 搜索视图函数
在你的views.py里添加这个视图:
from django.shortcuts import render from .models import Business def search_businesses(request): # 从GET请求里获取搜索参数,默认空字符串 city_slug = request.GET.get('city', '') category_slug = request.GET.get('category', '') # 初始化查询集为所有商家 businesses = Business.objects.all() # 按分类过滤(用slug比name更准确,避免重名问题) if category_slug: businesses = businesses.filter(categories__slug=category_slug) # 按城市过滤 if city_slug: businesses = businesses.filter(city__slug=city_slug) # 要是想支持模糊搜索(比如输入城市名的一部分也能搜到),可以改成下面这样: # if city_slug: # businesses = businesses.filter(city__name__icontains=city_slug) # if category_slug: # businesses = businesses.filter(categories__name__icontains=category_slug) # 把结果和搜索参数传给模板 context = { 'businesses': businesses, 'current_city': city_slug, 'current_category': category_slug } return render(request, 'businesses/search_results.html', context)
2. 前端搜索表单
在你的模板里添加搜索表单,让用户输入城市和分类:
<form method="get" action="{% url 'search_businesses' %}"> <div class="search-item"> <label for="city">城市</label> <input type="text" name="city" id="city" value="{{ current_city }}" placeholder="输入城市Slug或名称"> </div> <div class="search-item"> <label for="category">分类</label> <input type="text" name="category" id="category" value="{{ current_category }}" placeholder="输入分类Slug或名称"> </div> <button type="submit">搜索商家</button> </form>
3. 配置URL
在你的urls.py里添加搜索的路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('search/', views.search_businesses, name='search_businesses'), ]
对应三种搜索场景
- 所有城市中的某类商家:只填分类参数,不填城市,视图会返回全平台该分类的所有商家
- 某个城市中的所有商家:只填城市参数,不填分类,视图会返回该城市下的所有商家(改成
ForeignKey后会有多个结果,OneToOne最多一个) - 某个城市中的某类商家:同时填城市和分类参数,视图会返回该城市下属于该分类的商家
这种方式的好处很明显:代码简洁易维护,查询效率高,还能轻松扩展排序、分页、距离搜索等功能。
内容的提问来源于stack exchange,提问作者skerdilajd hoxha
相关产品推荐
相关产品推荐

