Django:计算项目并按父类别和子类别排序

时间:2013-01-04 15:55:14

标签: django

我希望有人可以提供帮助。我希望获得类似于您在分类网站或博客上看到的内容,其中您有一个带有类别的侧边栏(包含子类别的父类别)以及该父类别和子类别中分类广告或博客帖子的数量。看起来像这样:

Sidebar: Showing a count of all ads in the parent category and in the children categories

这是我的模特

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(),但无济于事,除非我当然没有做对。我不确定此时最好的方法是什么,但我确信之前有人这样做过,我不需要重新发明轮子。

0 个答案:

没有答案