我想在Django的父类别下显示子类别标题和它的项目,例如,我有1个父类别,然后它有2个子猫,然后他们每个人有3个子猫。在每个子类别中有10个项目。
Parental category1
item1
item2
subcategory 1
item3
item4
item5
child category 1 from subcategory1
item6
item7
subcategory 2
item8
item9
item10
下面是我的代码:
Models.py
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils.text import slugify
from mptt.models import MPTTModel, TreeForeignKey
class Category(MPTTModel):
name = models.CharField(max_length=settings.BLOG_TITLE_MAX_LENGTH, unique=True)
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children')
slug = models.SlugField(max_length=settings.BLOG_TITLE_MAX_LENGTH, null=True, blank=True)
description = models.TextField(null=True, blank=True)
class MPTTMeta:
order_insertion_by = ['name']
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.name
def save(self, *args, **kwargs):
value = self.name
if not self.slug:
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
def get_absolute_url(self):
return reverse('items-by-category', args=[str(self.slug)])
class Item(models.Model):
title = models.CharField(max_length=settings.BLOG_TITLE_MAX_LENGTH)
category = TreeForeignKey('Category', on_delete=models.CASCADE, null=True, blank=True)
description = models.TextField(null=True, blank=True)
slug = models.SlugField(
max_length=settings.BLOG_TITLE_MAX_LENGTH,
)
def __str__(self):
return self.title
def get_absolute_url(self):
kwargs = {
'slug': self.slug
}
return reverse('item-detail', kwargs=kwargs)
def save(self, *args, **kwargs):
if not self.slug:
value = self.title
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
Views.py
from django.views import generic
from .models import Item, Category
class CategoryListView(generic.ListView):
model = Category
template_name = "blog/category_list.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['items'] = Item.objects.all()
return context
class ItemsByCategoryView(generic.ListView):
ordering = 'id'
paginate_by = 10
template_name = 'blog/items_by_category.html'
def get_queryset(self):
# https://docs.djangoproject.com/en/3.1/topics/class-based-views/generic-display/#dynamic-filtering
# the following category will also be added to the context data
self.category = Category.objects.get(slug=self.kwargs['slug'])
queryset = Item.objects.filter(category=self.category)
# need to set ordering to get consistent pagination results
queryset = queryset.order_by(self.ordering)
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['category'] = self.category
return context
class ItemDetailView(generic.DetailView):
model = Item
template_name = 'blog/item_detail.html'
items_by_category.html
{% extends "blog/base.html" %}
{% block title %}{{category.name}} list of items{% endblock %}
{% block content %}
<main>
<section>
<div class="container">
<h1>{{category}} items</h1>
<p>{{category.description}}.</p>
</div>
</section>
{% include "blog/_breadcrumbs.html" with ancestors=category.get_ancestors object=category%}
<div>
{% for item in object_list%}
<div>
<a href="{{item.get_absolute_url}}">
<p>{{item}}</p>
</a>
</div>
{% endfor %}
{% if is_paginated %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
{% endif %}
</div>
</main>
{% endblock %}
谢谢
我尝试显示家长类别,但未显示任何内容
2条答案
按热度按时间fdx2calv1#
在这里我试图解决这样一个问题...
从here克隆Github存储库
浏览器输出
xxb16uws2#
看看docs,您可能需要执行以下几个步骤:
首先,您的查询集只查找一个类别,您还需要该类别的子类别。MPTT模型有一些额外的模型函数来帮助您遍历树。在本例中,get_descendants是相关的,因为我们可以在集合中保留原始示例。(注:如果你想从页面的树中得到 * 所有的东西 *,你可以使用get_family())
现在我们有一个完整的查询集来查找其中的项目,因此我们需要调整查询集
所以这将提供所有按类别分组的项。你可以使用这个方法轻松地得到一个平面列表,但是我们需要缩进。不幸的是,因为我们抓取的是项而不是类别,所以我们不能使用MPTT递归模板循环遍历类别并对treeForeignKey子项进行分类-为此,我们必须创建一个类别的查询集,并使用prefetch_related来获取项,例如:
现在,我们可以在模板中使用类似以下内容: