我希望有人可以提供帮助。我希望获得类似于您在分类网站或博客上看到的内容,其中您有一个带有类别的侧边栏(包含子类别的父类别)以及该父类别和子类别中分类广告或博客帖子的数量。看起来像这样:
这是我的模特
class Category(models.Model):
name = models.CharField(max_length=120, unique=True)
slug = models.SlugField(null=False, editable=False)
parent = models.ForeignKey('self', null=True, blank=True, related_name='child_set')
class Classified(models.Model):
category = models.ForeignKey(Category, related_name='categories')
title = models.CharField(max_length=255, null=False, unique=True, blank=False)
price = models.CharField(max_length=10, null=False, blank=False, default=0)
description = models.TextField(null=False, blank=True, editable=True)
user = models.ForeignKey(User)
sold = models.BooleanField(blank=True, default=False)
slug = models.SlugField(max_length=255, null=False, editable=False)
这是我的模板标签:
class Categories(template.Node):
def render(self, context):
categories = Category.objects.filter(parent=None).order_by('parent')
context['categories'] = categories
return ''
以下是我获取计数的模板过滤器:
# Parent Category Count
@register.filter
def parent_category_count(value):
count = Classified.objects.select_related().filter(category__in=Category.objects.filter(parent=value)).exclude(sold=True).count()
return count
# Child Category Count
@register.filter
def child_category_count(value):
count = Classified.objects.select_related().filter(category=value).exclude(sold=True).count()
return count
这是我的模板:
{% regroup categories by parent as cat_list %}
{% for parent in cat_list %}
<ul class="category">
{% for item in parent.list %}
<li class="parent-category-item">
{% block parent-category %}
{% if item|parent_category_count %}
<span class="category-count">{{ item|parent_category_count }}</span>
{% else %}
{% endif %}
<a {% if item.name == category %}class="parent selected"{% else %}class="parent"{% endif %} href="{% url classifieds_home %}{{ item.slug }}/">{{ item.name }}</a>
{% endblock %}
</li>
<ul {% if item.name == category %}class="child-categories"{% else %}class="child-categories hide"{% endif %}>
{% for i in item.child_set.all %}
<li class="child-category-item">
{% block category_child %}
{% if i|child_category_count %}
<span class="category-count">{{ i|child_category_count }}</span>
{% else %}
{% endif %}
<a {% if i.name == child_category %}class="child selected"{% else %}class="child"{% endif %} href="{% url classifieds_home %}{{ item.slug }}/{{ i.slug }}/">{{ i.name }}</a>
{% endblock %}
</li>
{% endfor %}
</ul>
{% endfor %}
</ul>
{% endfor %}
我已经厌倦了使用模板标签,除了计数之外,它还可以使用。我厌倦了使用自定义模板过滤器来获取每个类别的计数,但这需要很长时间(在141.91ms内有277个查询)。
所以我知道过滤器计数导致数据库多次被击中,这是不好的。如果子计数可以在父计数加载速度快的情况下工作,那么一切都会有效,但我猜这与父母类别较少有关。
我也厌倦了在Django中使用raw(),extra()和annotate(),但无济于事,除非我当然没有做对。我不确定此时最好的方法是什么,但我确信之前有人这样做过,我不需要重新发明轮子。