誰かが助けてくれることを願っています。カテゴリ (子カテゴリを持つ親カテゴリ) を含むサイドバーと、その親カテゴリと子カテゴリ内の分類された広告またはブログ投稿の数のカウントがある、分類されたサイトまたはブログで表示されるものと同様のものを実現したいと考えています。次のようになります。
これが私のモデルです
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.91 ミリ秒で 277 クエリ)。
したがって、フィルター カウントが原因でデータベースが複数回ヒットすることはわかっていますが、これは良くありません。親のカウントが高速に読み込まれるため、子のカウントが機能する場合はすべて機能しますが、それは親のカテゴリが少ないことに関係していると思います.
また、Django で raw()、extra()、annotate() を使用するのにも疲れましたが、もちろん正しく行っていない限り、役に立ちませんでした。この時点で何が最善のアプローチかはわかりませんが、誰かが以前にこれを行ったことがあるので、車輪を再発明する必要はないと確信しています。