Django忽略过滤器

时间:2019-07-24 13:27:57

标签: python django django-rest-framework django-views

我正在尝试为我的电子商务网站项目创建一个简单的“搜索”功能,该功能的数据库中包含多种产品。

models.py

    INR='₹'
    USD='$'
    CURRENCY_LIST=[(INR,'INR'),(USD,'USD')]
    subcategory=models.ForeignKey(Subcategory,on_delete=models.CASCADE)
    category=models.ForeignKey(Category,on_delete=models.CASCADE)
    name=models.CharField(max_length=50)
    price=models.DecimalField(max_digits=8,decimal_places=2,db_column='price')
    currency=models.CharField(max_length=3,choices=CURRENCY_LIST,default=INR,db_column='currency')
    view_count=models.IntegerField(default=0)
    @property
    def combined(self):
        return self.price+self.currency

    class Meta:
        db_table='Products'
        verbose_name_plural='products'
    def __str__(self):
        return self.name    

serializers.py

    class Meta:
        model=Products
        fields='__all__'
views.py
    def get(self,request):
        if request.method=="GET":
            search=request.query_params['search']
            sort=request.query_params['sort']
            start,end=request.query_params['filter'].split('-')
            q1=Products.objects.filter(name__icontains=search)
            q2=Products.objects.filter(subcategory__name__icontains=search)
            q3=Products.objects.filter(category__name__icontains=search)
            q1=q1.union(q2,q3)
            if sort=="low to high":
                q1=q1.filter(price__gte=start,price__lte=end).order_by('name','price')
                serializer=ProductsSerializer(q1,many=True)
                return JsonResponse({"response":serializer.data})
            elif sort=="high to low":
                q1=q1.filter(price__gte=start,price__lte=end).order_by('-price','name')
                return JsonResponse({"response":serializer.data})               
            elif sort=="most popular":
                q1=q1.filter(price__gte=start,price__lte=end).order_by('views')
                return JsonResponse({"response":serializer.data})

在第二个“ if”块开始之前(在views.py文件中),我获得了正确的搜索结果。但是之后,Django仅返回相同的未过滤查询集。

这是print(q1.query)的结果。

(SELECT `Products`.`id`, `Products`.`subcategory_id`, `Products`.`category_id`, `Products`.`name`, `Products`.`price`, `Products`.`currency`, `Products`.`view_count` FROM `Products` WHERE `Products`.`name` LIKE %shirt%) UNION (SELECT `Products`.`id`, `Products`.`subcategory_id`, `Products`.`category_id`, `Products`.`name`, `Products`.`price`, `Products`.`currency`, `Products`.`view_count` FROM `Products` INNER JOIN `Subcategory` ON (`Products`.`subcategory_id` = `Subcategory`.`id`) WHERE `Subcategory`.`name` LIKE %shirt%) UNION (SELECT `Products`.`id`, `Products`.`subcategory_id`, `Products`.`category_id`, `Products`.`name`, `Products`.`price`, `Products`.`currency`, `Products`.`view_count` FROM `Products` INNER JOIN `Category` ON (`Products`.`category_id` = `Category`.`id`) WHERE `Category`.`name` LIKE %shirt%) ORDER BY (4) ASC, (5) ASC

1 个答案:

答案 0 :(得分:2)

首先,最好在此处使用单个查询集,例如:

from django.db.models import Q
from decimal import Decimal

search=request.query_params['search']
sort=request.query_params['sort']
start,end=request.query_params['filter'].split('-')

q1 = Products.objects.filter(
    Q(name__icontains=search) |
    Q(subcategory__name__icontains=search) |
    Q(category__name__icontains=search)
).filter(price__gte=Decimal(start),price__lte=Decimal(end))

接下来,您可以让search参数决定如何订购商品,例如:

if sort == 'low to high':
    q1 = q1.order_by('price', 'name')
elif sort == 'high to low':
    q1 = q1.order_by('-price', 'name')               
elif sort == 'most popular':
    q1 = q1.order_by('views')

最后,您序列化并返回响应:

serializer = ProductsSerializer(q1,many=True)
return JsonResponse({'response': serializer.data})