发布于2023-08-21 23:34 阅读(1056) 评论(0) 点赞(17) 收藏(4)
我希望能够搜索一个产品,其类别不直接链接到它,但该类别是祖父或曾祖父等,在实际链接到产品本身的类别的类别树上。我可以实现的唯一方法是使用以下方法,这当然是不可扩展的和正确的方法:
def get_queryset(self, request):
queryset = super().get_queryset(request).select_related('brand', 'category', 'category__parent')
category_name = request.GET.get('category__name', None)
if category_name:
# Filter the queryset to include products with the specified category or its ancestors
queryset = queryset.filter(
Q(category__name=category_name) |
Q(category__parent__name=category_name) |
Q(category__parent__parent__name=category_name) |
# Add more levels as needed based on the depth of your category tree
)
return queryset
这是目前的代码:
Product``models.py
class Product(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
image = models.ImageField(upload_to='product_images/')
category = models.ForeignKey(Category, on_delete=models.SET_NULL,related_name='product_category', null=True, blank=True)
brand = models.ForeignKey(Brand, on_delete=models.SET_NULL, related_name='product_brand', null=True, blank=True)
tags = GenericRelation(TaggedItem, related_query_name='product')
ratings = GenericRelation(Rating, related_query_name='product')
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
state = models.CharField(max_length=2, choices=PublishStateOptions.choices, default=PublishStateOptions.DRAFT)
publish_timestamp = models.DateTimeField(
# means that the publish_timestamp field will not automatically be set to the current date and time when a new instance of this model is created.
auto_now_add=False,
# means that the publish_timestamp field will not automatically be updated to the current date and time every time the model is saved.
auto_now=False,
blank=True,
null=True
)
def __str__(self):
return self.name
Category``models.py
class Category(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='subcategories', null=True, blank=True)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
Product``admin.py
class ProductAdmin(admin.ModelAdmin):
list_display = ['name', 'price', 'brand', 'category']
inlines = [TaggedItemInline]
list_filter = [
'brand__name',
'category__name'
]
search_fields = ['name', 'price', 'brand__name', 'category__name', 'category__parent__name']
def get_queryset(self, request):
return super().get_queryset(request).select_related('brand', 'category', 'category__parent')
def get_brand_name(self, obj):
return obj.brand.name if obj.brand else None
def get_category_name(self, obj):
return obj.category.name if obj.category else None
get_brand_name.short_description = 'Brand'
get_category_name.short_description = 'Category'
# Define the labels for list filters
list_filter = (
('brand', admin.RelatedOnlyFieldListFilter),
('category', admin.RelatedOnlyFieldListFilter),
)
admin.site.register(Product, ProductAdmin)
一个小时后,我明白了。
def get_search_results(self, request, queryset, search_term):
queryset, use_distinct = super().get_search_results(request, queryset, search_term)
# Search for products based on ascendant category names recursively
matching_categories = self.find_matching_categories(search_term)
ascendant_categories = self.get_all_ascendant_categories(matching_categories)
products_with_ascendant_categories = self.model.objects.filter(category__in=ascendant_categories)
queryset |= products_with_ascendant_categories
return queryset, use_distinct
def find_matching_categories(self, search_term):
# Find categories that match the search term
return Category.objects.filter(name__icontains=search_term)
def get_all_ascendant_categories(self, categories):
# Recursively retrieve all ascendant categories
ascendant_categories = list(categories)
new_ascendants = Category.objects.filter(parent__in=categories)
if new_ascendants:
ascendant_categories.extend(self.get_all_ascendant_categories(new_ascendants))
return ascendant_categories
当用户搜索产品时,他们现在可以使用该产品类别的上级名称。get_search_results() 方法经过定制以实现此目的。当用户搜索时,代码会识别与搜索词匹配的类别,然后递归地收集这些类别的所有祖先。这可确保搜索结果中包含类别及其后代的产品。
作者:黑洞官方问答小能手
链接:https://www.pythonheidong.com/blog/article/2012824/343a2ab8fbd22f82f9db/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!