You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Ajax实现Django中商品内容筛选功能的技术求助

嘿,我来帮你梳理下怎么实现这个商品属性筛选功能,先从你给出的地区模型说起,看起来你已经搭好了国家、地区、城市的关联框架,接下来咱们一步步落地:

商品属性筛选功能实现指南

1. 先补全你的地区模型

你给出的City模型代码没写完,我先帮你补全并优化下,方便后续关联和查询:

"""国家、地区和城市表"""
class Country(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return self.name

class Region(models.Model):
    name = models.CharField(max_length=200)
    country = models.ForeignKey(Country, on_delete=models.CASCADE, related_name="regions")

    def __str__(self):
        return f"{self.country.name} - {self.name}"

class City(models.Model):
    name = models.CharField(max_length=200)
    region = models.ForeignKey(Region, on_delete=models.CASCADE, related_name="cities")

    def __str__(self):
        return f"{self.region.country.name} - {self.region.name} - {self.name}"

这里加了related_name方便反向查询关联数据,__str__方法能让模型在后台和模板里显示更友好的名称,避免直接显示对象ID。

2. 给商品模型关联属性字段

假设你的商品需要绑定地区、类别、品牌这类可筛选属性,模型可以这么设计:

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    # 关联城市(如果需要精准到城市粒度,也可以改成关联地区/国家,按需调整)
    city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True, blank=True)
    # 其他可筛选属性示例
    category = models.CharField(max_length=100)
    brand = models.CharField(max_length=100)

    def __str__(self):
        return self.name

3. 视图层实现筛选逻辑

在视图里接收前端传来的筛选参数,动态过滤商品QuerySet,还做了地区联动筛选(选国家后只显示对应地区,选地区后只显示对应城市):

from django.shortcuts import render
from .models import Product, Country, Region, City

def product_list(request):
    # 初始商品数据集
    products = Product.objects.all()

    # 提取前端筛选参数
    country_id = request.GET.get('country')
    region_id = request.GET.get('region')
    city_id = request.GET.get('city')
    category = request.GET.get('category')
    brand = request.GET.get('brand')

    # 按地区层级筛选
    if country_id:
        products = products.filter(city__region__country_id=country_id)
    if region_id:
        products = products.filter(city__region_id=region_id)
    if city_id:
        products = products.filter(city_id=city_id)

    # 按其他属性筛选
    if category:
        products = products.filter(category=category)
    if brand:
        products = products.filter(brand=brand)

    # 准备筛选下拉选项数据(联动逻辑)
    countries = Country.objects.all()
    regions = Region.objects.all()
    if country_id:
        regions = regions.filter(country_id=country_id)
    cities = City.objects.all()
    if region_id:
        cities = cities.filter(region_id=region_id)
    # 提取商品的唯一类别、品牌选项
    categories = Product.objects.values_list('category', flat=True).distinct()
    brands = Product.objects.values_list('brand', flat=True).distinct()

    # 把当前选中的参数传回模板,用于回显选中状态
    context = {
        'products': products,
        'countries': countries,
        'regions': regions,
        'cities': cities,
        'categories': categories,
        'brands': brands,
        'selected_country': country_id,
        'selected_region': region_id,
        'selected_city': city_id,
        'selected_category': category,
        'selected_brand': brand,
    }
    return render(request, 'product_list.html', context)

4. 模板层渲染筛选表单和商品列表

在product_list.html里实现筛选表单和商品展示,同时保留选中状态提升用户体验:

<!-- 筛选表单 -->
<form method="get" class="filter-form">
    <div class="filter-group">
        <label for="country">国家:</label>
        <select name="country" id="country" onchange="this.form.submit()">
            <option value="">全部</option>
            {% for country in countries %}
                <option value="{{ country.id }}" {% if selected_country == country.id|stringformat:"i" %}selected{% endif %}>
                    {{ country.name }}
                </option>
            {% endfor %}
        </select>
    </div>

    <div class="filter-group">
        <label for="region">地区:</label>
        <select name="region" id="region" onchange="this.form.submit()">
            <option value="">全部</option>
            {% for region in regions %}
                <option value="{{ region.id }}" {% if selected_region == region.id|stringformat:"i" %}selected{% endif %}>
                    {{ region.name }}
                </option>
            {% endfor %}
        </select>
    </div>

    <div class="filter-group">
        <label for="city">城市:</label>
        <select name="city" id="city" onchange="this.form.submit()">
            <option value="">全部</option>
            {% for city in cities %}
                <option value="{{ city.id }}" {% if selected_city == city.id|stringformat:"i" %}selected{% endif %}>
                    {{ city.name }}
                </option>
            {% endfor %}
        </select>
    </div>

    <div class="filter-group">
        <label for="category">类别:</label>
        <select name="category" id="category" onchange="this.form.submit()">
            <option value="">全部</option>
            {% for category in categories %}
                <option value="{{ category }}" {% if selected_category == category %}selected{% endif %}>
                    {{ category }}
                </option>
            {% endfor %}
        </select>
    </div>

    <div class="filter-group">
        <label for="brand">品牌:</label>
        <select name="brand" id="brand" onchange="this.form.submit()">
            <option value="">全部</option>
            {% for brand in brands %}
                <option value="{{ brand }}" {% if selected_brand == brand %}selected{% endif %}>
                    {{ brand }}
                </option>
            {% endfor %}
        </select>
    </div>

    <button type="submit" class="filter-btn">筛选</button>
</form>

<!-- 商品列表展示 -->
<div class="product-list">
    {% for product in products %}
        <div class="product-item">
            <h3>{{ product.name }}</h3>
            <p>价格: {{ product.price }}元</p>
            {% if product.city %}
                <p>产地: {{ product.city }}</p>
            {% endif %}
            <p>类别: {{ product.category }}</p>
            <p>品牌: {{ product.brand }}</p>
        </div>
    {% empty %}
        <p>没有找到符合条件的商品</p>
    {% endfor %}
</div>

这里用onchange="this.form.submit()"实现选择后自动提交筛选,你也可以改成点击按钮提交;同时通过模板判断把选中的选项标记出来,用户能清楚看到当前筛选条件。

5. 可选进阶优化

  • 如果商品数据量大,记得用Paginator做分页,避免页面加载过慢;
  • 可以用AJAX实现无刷新筛选,用户体验更流畅,比如用jQuery监听下拉框变化,异步请求数据更新商品列表;
  • 支持多选筛选的话,可以把下拉框改成多选控件,视图里用request.GET.getlist('category')接收参数,然后用filter(category__in=选中列表)过滤。

内容的提问来源于stack exchange,提问作者GuardianAngel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:40:11