我正在尝试为我的电子商务网站项目创建一个简单的“搜索”功能,该功能的数据库中包含多种产品。
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
答案 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})