You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 2.0.1模板中按分类展示对应物品的实现问题

实现Django分类下物品的关联展示

嘿,我帮你梳理下如何实现每个分类下展示对应物品的需求,首先你的代码里有几个小笔误得先修正,不然运行会报错,接下来一步步来:

1. 修正模型中的笔误

你代码里的外键引用和模型类名不匹配:

  • CategoryItems的外键写的是Categories,但你的模型类实际是Category
  • 视图里的Categories.objects.all()和CategoriesItems.objects.all()也写错了类名

修正后的models.py:

from django.db import models

class Category(models.Model):
    category_name = models.CharField(max_length=50)

    # 可选:给模型实例添加友好的显示名称
    def __str__(self):
        return self.category_name

class CategoryItems(models.Model):
    # 这里修正为Category,而非Categories
    category = models.ForeignKey(Category, related_name='categoriesfk', on_delete=models.PROTECT)
    item_name = models.CharField(max_length=50)
    item_description = models.CharField(max_length=100)

    def __str__(self):
        return self.item_name

2. 优化视图查询

不需要单独查询物品列表,利用Django的反向关联和prefetch_related来一次性获取分类及其关联的物品,这样能避免N+1查询问题,提升性能。

修正后的views.py:

from django.shortcuts import render
from .models import Category

def data(request):
    # 使用prefetch_related预加载关联的物品
    categories_query = Category.objects.prefetch_related('categoriesfk').all()
    return render(request, "data.html", {'categories_query': categories_query})

3. 模板中实现嵌套展示

在data.html里通过嵌套循环,先遍历每个分类,再遍历该分类下的所有物品:

<!DOCTYPE html>
<html>
<head>
    <title>分类与物品展示</title>
</head>
<body>
    {% for category in categories_query %}
        <h3>{{ category.category_name }}</h3>
        <ul>
            {% for item in category.categoriesfk.all %}
                <li>
                    <strong>{{ item.item_name }}</strong>: {{ item.item_description }}
                </li>
            {% empty %}
                <li>该分类下暂无物品</li>
            {% endfor %}
        </ul>
    {% endfor %}
</body>
</html>

这样就能实现你想要的效果:每个分类作为标题,下面列出该分类下的所有物品,如果分类没有物品,还会显示提示文本。

内容的提问来源于stack exchange,提问作者user9305920

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:18:26