Django 2.0下实现Admin后台字段级独立搜索功能
Django 2.0 实现多字段独立搜索功能(针对WallmartRecord模型)
既然你已经搞定了models.py里的WallmartRecord模型,那接下来咱们一步步实现每个字段带独立输入框的搜索功能,完全适配Django 2.0哈~
第一步:创建搜索表单(forms.py)
首先得写个表单类,把每个需要搜索的字段都做成独立的输入框,用户可以填任意一个或多个字段来搜索。在你的app目录下新建forms.py,写下面的代码:
from django import forms from .models import WallmartRecord class WallmartSearchForm(forms.Form): name = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': '按名称搜索'})) upc = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': '按UPC搜索'})) price = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': '按价格搜索'})) category = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': '按分类搜索'}))
这里required=False是允许用户不填某些字段,只搜自己关心的;placeholder是给输入框加提示文字,用户体验更好。
第二步:编写视图函数(views.py)
接下来要写视图处理搜索逻辑:获取用户输入的搜索条件,过滤数据库里的记录。打开views.py,添加下面的函数:
from django.shortcuts import render from .models import WallmartRecord from .forms import WallmartSearchForm from django.db.models import Q def wallmart_search(request): # 初始化表单,GET请求时带上用户输入的参数 form = WallmartSearchForm(request.GET or None) # 默认获取所有记录 records = WallmartRecord.objects.all() if form.is_valid(): # 取出每个字段的搜索值 name_query = form.cleaned_data.get('name') upc_query = form.cleaned_data.get('upc') price_query = form.cleaned_data.get('price') category_query = form.cleaned_data.get('category') # 构建过滤条件:只有用户填了的字段才参与过滤 filter_conditions = Q() if name_query: # __icontains是不区分大小写的包含搜索,适合字符串字段 filter_conditions &= Q(name__icontains=name_query) if upc_query: filter_conditions &= Q(upc__icontains=upc_query) if price_query: filter_conditions &= Q(price__icontains=price_query) if category_query: filter_conditions &= Q(category__icontains=category_query) # 应用过滤条件 records = records.filter(filter_conditions) # 把表单和结果传给模板 return render(request, 'wallmart/search.html', {'form': form, 'records': records})
这里用Q对象来组合多个过滤条件,保证只有用户填写了的字段才会被用来过滤,没填的字段不影响结果。
第三步:配置URL路由(urls.py)
现在要给搜索页面配个URL,打开app目录下的urls.py(如果没有就新建一个),添加路由:
from django.urls import path from . import views urlpatterns = [ # 其他已有的路由... path('wallmart/search/', views.wallmart_search, name='wallmart_search'), ]
这样用户访问your-domain.com/wallmart/search/就能看到搜索页面了。
第四步:编写模板文件
最后写个模板来展示搜索表单和结果。在app的templates目录下新建wallmart/search.html(目录结构要对应),写下面的代码:
<!DOCTYPE html> <html> <head> <title>Wallmart记录搜索</title> <!-- 加一点简单样式让页面更整齐 --> <style> .search-form { margin: 20px 0; } .search-form input { margin: 0 5px; padding: 8px 12px; width: 200px; border: 1px solid #ddd; border-radius: 4px; } .search-form button { padding: 8px 16px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; } .results-table { margin-top: 20px; border-collapse: collapse; width: 100%; } .results-table th, .results-table td { border: 1px solid #ddd; padding: 10px; text-align: left; } .results-table th { background-color: #f8f9fa; } </style> </head> <body> <h2>Wallmart商品记录搜索</h2> <!-- 用GET方法提交表单,参数会显示在URL里,方便分享 --> <form class="search-form" method="get"> {{ form.name }} {{ form.upc }} {{ form.price }} {{ form.category }} <button type="submit">搜索</button> </form> <div class="search-results"> {% if records %} <table class="results-table"> <thead> <tr> <th>商品名称</th> <th>UPC码</th> <th>价格</th> <th>分类</th> </tr> </thead> <tbody> {% for record in records %} <tr> <td>{{ record.name }}</td> <td>{{ record.upc }}</td> <td>{{ record.price }}</td> <td>{{ record.category }}</td> </tr> {% endfor %} </tbody> </table> {% else %} <p>暂无匹配的商品记录</p> {% endif %} </div> </body> </html>
模板里会自动渲染每个表单字段对应的独立输入框,用户填完点搜索就能看到过滤后的结果了。
小提示(适配Django 2.0)
- 如果你需要精确匹配(比如UPC码必须完全一致),可以把代码里的
__icontains换成__exact,不过包含搜索通常更符合用户的搜索习惯。 - 注意你的
price字段现在是CharField,如果以后需要做价格范围搜索,建议改成DecimalField,这样能更好地处理数值类型。
内容的提问来源于stack exchange,提问作者Anuj TBE
相关产品推荐
相关产品推荐

