【问题标题】:Django-MPTT Template: Subcategories not rendered when in recursetreeDjango-MPTT 模板:在递归树中未呈现子类别
【发布时间】:2020-07-24 13:45:28
【问题描述】:

我正在为我的电子商务网站构建一个类别和子类别树。类别模型本身有一个 TreeForeignKey,因此类别可以有许多其他子类别作为子类别。在我的 product.html 路由中,我成功地使用 {& recursettree [models] &} 标签渲染了类别树(见下面的第一张图片)。当用户点击说“泵”链接时,用户将被带到另一个页面,该页面仅显示“泵”及其子类别。然而,当我试图用 {& recursettree [models] &} 复制同样的东西时,它没有成功。我只看到“Pumps”父类,没有看到它的子类。我已经确保我将一个树查询集传递到递归树标记中,这样我就不会遇到“对象不可下标错误”。但是,我遇到了障碍,不知道我的代码有什么问题。

models.py

from django.db import models
from mptt.models import MPTTModel, TreeForeignKey, TreeManyToManyField
from ckeditor_uploader.fields import RichTextUploadingField
from django.urls import reverse

# Create your models here.

class Category(MPTTModel):

    Status = (
        ('True', 'True'),
        ('False', 'False'),
    )

    bool_choices = (
        (True, 'Yes'),
        (False, 'No'),
    )

    parent = TreeForeignKey('self',  blank = True, null = True, related_name = 'children', on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    slug = models.SlugField(unique=True, null=False)
    description = models.TextField()
    status = models.CharField(max_length=10, choices = Status)
    is_active = models.BooleanField(choices=bool_choices)
    meta_keywords = models.CharField(max_length=255)
    meta_description = models.CharField(max_length=255)
    created_at = models.DateTimeField(auto_now_add = True)
    updated_at = models.DateTimeField(auto_now = True)
    image = models.ImageField(blank = True, upload_to = 'images/')

    class Meta:
        db_table = 'categories'
        verbose_name_plural = 'Categories'

    def __str__(self):
        return f"{self.name}"

    class MPTTMeta:
        order_insertion_by = ['name']

    def get_absolute_url(self):
        
        return reverse('category_detail', kwargs={'slug':self.slug})

views.py

def product(request):

    category = Category.objects.all()
    context = {'category': category}
    return render(request, 'product.html', context)


def category(request, slug):

    category = Category.objects.all().filter(slug=slug)
    context = {'category': category}
    return render(request, 'category.html', context)

urls.py

from django.urls import path
from . import views 
from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [
    path("product/", views.product, name='product'),
    path("<str:slug>/", views.category, name='category'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

product.html

{% extends 'layout.html' %}

{% block title %}

{% endblock %}


{% block body %}
<div>
    {% load mptt_tags %}
    <div class = "container">
        <ul class="root">
          {% recursetree category %}
              <li>
                  <a href="{% url 'category' node.slug %}">{{ node.name }}</a>
                  {% if not node.is_leaf_node %}
                      <ul class="children">
                          {{ children }}
                      </ul>
                  {% endif %}
              </li>
          {% endrecursetree %}
        </ul>
    </div>
</div>
{% endblock %}

[在 product.html 中成功呈现的类别及其子类别] [1]:https://i.stack.imgur.com/WO2ZH.png

category.html

{% extends 'layout.html' %}

{% block title %}
    {{ category.id }}
{% endblock %}

{% block body %}

    {% load mptt_tags %}
    <div class = "container">
        <ul class="root">
          {% recursetree category %}
              <li>
                  <a href="{% url 'category' node.slug %}">{{ node.name }}</a>
                  {% if not node.is_leaf_node %}
                      <ul class="children">
                          {{ children }}
                      </ul>
                  {% endif %}
              </li>
          {% endrecursetree %}
        </ul>
    </div>
{% endblock %}

[Pumps 的子类别未能在 category.html 中呈现] [2]:https://i.stack.imgur.com/6DRkQ.png

【问题讨论】:

    标签: django-mptt


    【解决方案1】:

    category = Category.objects.all().filter(slug=slug) 的输出仅是 ]>。

    如果我还需要渲染孩子,我需要调用以下行来获取后代和模型实例本身。

    category = category.get_descendants(include_self=True)
    

    【讨论】: