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

Django中如何根据Product的Attribute属性筛选商品

模型关联优化(可选但推荐)

先给ProductAttribute的外键添加反向关联名,方便后续跨表查询:

class ProductAttribute(models.Model):
    # 新增related_name,后续Product可直接通过attributes访问关联的属性
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='attributes')
    # 其余字段保持原有逻辑不变
    size = models.ForeignKey(Size, on_delete=models.CASCADE, null=True, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2, validators=[MinValueValidator(1)])
    discounted_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
    stock = models.CharField(max_length=10, null=True)

编写django_filters筛选器类

import django_filters
from .models import Product, Size

class ProductFilter(django_filters.FilterSet):
    # 单尺码筛选:传尺码ID查询对应商品
    size = django_filters.ModelChoiceFilter(
        queryset=Size.objects.all(),
        field_name='attributes__size',  # 跨反向关联查询属性的size字段
        label='尺码',
        distinct=True  # 避免同一商品关联多个属性时返回重复结果
    )

    # 可选配置1:多尺码同时筛选,支持传多个尺码ID查询
    # size = django_filters.ModelMultipleChoiceFilter(
    #     queryset=Size.objects.all(),
    #     field_name='attributes__size',
    #     lookup_expr='in',
    #     label='多尺码筛选',
    #     distinct=True
    # )

    # 可选配置2:直接传尺码值(如M/XL)筛选,前提是Size模型有存储尺码值的name字段
    # size_name = django_filters.CharFilter(
    #     field_name='attributes__size__name',
    #     lookup_expr='exact',
    #     label='尺码值',
    #     distinct=True
    # )

    class Meta:
        model = Product
        # 可按需添加其他需要筛选的字段,如分类、品牌、状态等
        fields = ['category', 'brand', 'status', 'size']

视图中使用筛选器

普通Django视图场景

from .filters import ProductFilter

def product_list(request):
    product_query = Product.objects.filter(status='Active')
    # 传入GET参数和查询集完成筛选
    filter_obj = ProductFilter(request.GET, queryset=product_query)
    # 筛选后的商品结果存储在filter_obj.qs中
    return render(request, 'product/list.html', {'products': filter_obj.qs, 'filter': filter_obj})

Django REST Framework视图场景

from rest_framework import viewsets
from .models import Product
from .filters import ProductFilter
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Product.objects.filter(status='Active')
    serializer_class = ProductSerializer
    filterset_class = ProductFilter  # 直接指定筛选器类即可生效

注意事项

  • distinct=True参数必须添加,跨一对多关联查询时,符合条件的关联属性有多条的话会返回重复的商品记录,该参数会自动完成去重。
  • 后续如果要新增颜色等其他商品属性,只要在ProductAttribute模型里加对应的外键字段,然后在筛选器里参照尺码的写法新增对应筛选字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:15:02