通过组合多个 Django 过滤器获得独特的输出
Get unique outputs from combining more than one Django filters
因此,我尝试在我的网站上创建一个搜索引擎,用户可以在其中输入查询,然后在产品 name
或 description
中存在查询的地方显示这些结果。我的产品型号如下:-
'''Product model to store the details of all the products'''
class Product(models.Model):
# Define the fields of the product model
name = models.CharField(max_length=100)
price = models.IntegerField(default=0)
quantity = models.IntegerField(default=0)
description = models.CharField(max_length=200, default='', null=True, blank=True)
image = models.ImageField(upload_to='uploads/images/products')
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1) # Foriegn key with Category Model
store = models.ForeignKey(Store, on_delete=models.CASCADE, default=1)
现在,我创建了一个搜索过滤器,我在其中按名称过滤,然后按描述过滤,然后将结果合并到 return 查询集。问题是有时可以在名称和描述中找到查询,所以我得到像这样的重复条目
我在 ProductView 中的过滤代码如下:-
class ProductView(generics.ListAPIView):
''' Product View to return the details of all the products and filter by ID or string '''
# Define class variables
queryset = []
# Manage a get request
def get(self, request):
''' Display all the products in our database if no id is passed
and if a store ID and search is passed then use those parameters'''
# Get all the parameters sent in the data
store_id = request.GET.get('store_id')
search_query = request.GET.get('search')
category = request.GET.get('category')
print(store_id, search_query, category)
queryset = Product.get_all_products()
# Apply filters to the data
if store_id:
queryset = queryset.filter(store=store_id)
if category:
queryset = queryset.filter(category=category)
if search_query:
# THIS IS WHERE THE SEARCH FILTERING SHOULD HAPPEN
names = queryset.filter(name__icontains=search_query)
descriptions = queryset.filter(description__icontains=search_query)
queryset = list(chain(names, descriptions))
return Response(ProductSerializer(queryset, many = True).data)
我希望只能得到一个结果,因为它是同一种产品。有没有一种方法只能将不同的结果保存在查询集中。我做了一个循环,检查 descriptions
中的结果是否该项目已经存在于名称中,但结果不是很好。我该如何解决这个问题?
我添加了一个 for 循环来完成这项工作,但如果有人有更好的解决方案,请将其留在评论中。这是我写的最终观点。
class ProductView(generics.ListAPIView):
''' Product View to return the details of all the products and filter by ID or string '''
# Define class variables
serializer_class = ProductSerializer
queryset = Product.objects.all()
search_fields = ['name','description']
filter_backends = (SearchFilter,)
queryset = []
# Manage a get request
def get(self, request):
''' Display all the products in our database if no id is passed
and if a store ID and search is passed then use those parameters'''
# Get all the parameters sent in the data
store_id = request.GET.get('store_id', None)
search_query = request.GET.get('search')
category = request.GET.get('category')
print(store_id, search_query, category)
queryset = Product.get_all_products()
# Apply filters to the data
if store_id:
queryset = queryset.filter(store=store_id)
if category:
queryset = queryset.filter(category=category)
if search_query:
pass
names = queryset.filter(name__icontains=search_query)
descriptions = queryset.filter(description__icontains=search_query)
# Iterate through the names and get all ids
ids = []
for i in range(len(names)):
ids.append(names[i].id)
print(type(names[i].id), print(type(names[i])))
# iterate through descriptions
for i in range(len(descriptions)):
if descriptions[i].id not in ids:
ids.append(descriptions[i].id)
queryset = Product.objects.filter(id__in=ids)
return Response(ProductSerializer(queryset, many = True).data)
你有两个问题。
首先,您永远不应该像那样评估和合并两个查询集结果。
如果您想要 select 所有具有名称或描述的实体 icontaining
您的 search_query
,请使用 Q
对象。
对于 select查询集中唯一的对象,使用 distinct
。
所以你可以把最后几行改成这样。
if search_query:
queryset = queryset.filter(
Q(name__icontains=search_query) | Q(description__icontains=search_query)
)
queryset = queryset.distinct() # probably won't be needed anymore
因此,我尝试在我的网站上创建一个搜索引擎,用户可以在其中输入查询,然后在产品 name
或 description
中存在查询的地方显示这些结果。我的产品型号如下:-
'''Product model to store the details of all the products'''
class Product(models.Model):
# Define the fields of the product model
name = models.CharField(max_length=100)
price = models.IntegerField(default=0)
quantity = models.IntegerField(default=0)
description = models.CharField(max_length=200, default='', null=True, blank=True)
image = models.ImageField(upload_to='uploads/images/products')
category = models.ForeignKey(Category, on_delete=models.CASCADE, default=1) # Foriegn key with Category Model
store = models.ForeignKey(Store, on_delete=models.CASCADE, default=1)
现在,我创建了一个搜索过滤器,我在其中按名称过滤,然后按描述过滤,然后将结果合并到 return 查询集。问题是有时可以在名称和描述中找到查询,所以我得到像这样的重复条目
我在 ProductView 中的过滤代码如下:-
class ProductView(generics.ListAPIView):
''' Product View to return the details of all the products and filter by ID or string '''
# Define class variables
queryset = []
# Manage a get request
def get(self, request):
''' Display all the products in our database if no id is passed
and if a store ID and search is passed then use those parameters'''
# Get all the parameters sent in the data
store_id = request.GET.get('store_id')
search_query = request.GET.get('search')
category = request.GET.get('category')
print(store_id, search_query, category)
queryset = Product.get_all_products()
# Apply filters to the data
if store_id:
queryset = queryset.filter(store=store_id)
if category:
queryset = queryset.filter(category=category)
if search_query:
# THIS IS WHERE THE SEARCH FILTERING SHOULD HAPPEN
names = queryset.filter(name__icontains=search_query)
descriptions = queryset.filter(description__icontains=search_query)
queryset = list(chain(names, descriptions))
return Response(ProductSerializer(queryset, many = True).data)
我希望只能得到一个结果,因为它是同一种产品。有没有一种方法只能将不同的结果保存在查询集中。我做了一个循环,检查 descriptions
中的结果是否该项目已经存在于名称中,但结果不是很好。我该如何解决这个问题?
我添加了一个 for 循环来完成这项工作,但如果有人有更好的解决方案,请将其留在评论中。这是我写的最终观点。
class ProductView(generics.ListAPIView):
''' Product View to return the details of all the products and filter by ID or string '''
# Define class variables
serializer_class = ProductSerializer
queryset = Product.objects.all()
search_fields = ['name','description']
filter_backends = (SearchFilter,)
queryset = []
# Manage a get request
def get(self, request):
''' Display all the products in our database if no id is passed
and if a store ID and search is passed then use those parameters'''
# Get all the parameters sent in the data
store_id = request.GET.get('store_id', None)
search_query = request.GET.get('search')
category = request.GET.get('category')
print(store_id, search_query, category)
queryset = Product.get_all_products()
# Apply filters to the data
if store_id:
queryset = queryset.filter(store=store_id)
if category:
queryset = queryset.filter(category=category)
if search_query:
pass
names = queryset.filter(name__icontains=search_query)
descriptions = queryset.filter(description__icontains=search_query)
# Iterate through the names and get all ids
ids = []
for i in range(len(names)):
ids.append(names[i].id)
print(type(names[i].id), print(type(names[i])))
# iterate through descriptions
for i in range(len(descriptions)):
if descriptions[i].id not in ids:
ids.append(descriptions[i].id)
queryset = Product.objects.filter(id__in=ids)
return Response(ProductSerializer(queryset, many = True).data)
你有两个问题。
首先,您永远不应该像那样评估和合并两个查询集结果。
如果您想要 select 所有具有名称或描述的实体 icontaining
您的 search_query
,请使用 Q
对象。
对于 select查询集中唯一的对象,使用 distinct
。
所以你可以把最后几行改成这样。
if search_query:
queryset = queryset.filter(
Q(name__icontains=search_query) | Q(description__icontains=search_query)
)
queryset = queryset.distinct() # probably won't be needed anymore