如何在Django模板中访问外键?分类层级显示异常求助
修复Django三级分类模板显示问题
问题背景
定义了主分类、分类、子分类三级关联模型,视图已将主分类查询集传递至模板,但仅主分类能正常展示,分类和子分类无法显示。
模型代码
class MainCategory(models.Model): name = models.CharField(max_length=100) def __str__(self) : return self.name class Category(models.Model): main_category = models.ForeignKey(MainCategory, on_delete=models.CASCADE, related_name="maincategory") name = models.CharField(max_length=100) def __str__(self) : return self.name + "--" + self.main_category.name class SubCategory(models.Model): category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="category_name") name = models.CharField(max_length=100) def __str__(self) : return self.name
原视图代码
def Home(request): sliders = Slider.objects.all() banners = BannerArea.objects.all() main_category = MainCategory.objects.all() context = { 'sliders' : sliders, 'banners' : banners, 'main_category' : main_category } return render(request, 'main/home.html', context)
原模板代码
<div class="cat__menu"> <nav id="mobile-menu" style="display: block;"> <ul> {% for i in main_category %} <li> <a href="shop.html"> {{ i.name }} <i class="far fa-angle-down"></i></a> <ul class="mega-menu"> {% for cat in i.category_set.all %} <li><a href="shop.html">{{cat.name}}</a> <ul class="mega-item"> {% for sub_cat in cat.subcategory_set.all %} <li><a href="product-details.html">{{sub_cat.name}}</a></li> {% endfor %} </ul> </li> {% endfor %} </ul> </li> {% endfor %} </ul> </nav> </div>
修复方案
1. 修正模板中的关联查询名称
模型定义时已指定related_name,因此不能使用Django默认的xxx_set语法,需改用自定义的关联名称:
- 主分类获取分类:将
i.category_set.all()改为i.maincategory.all()(对应Category模型的related_name="maincategory") - 分类获取子分类:将
cat.subcategory_set.all()改为cat.category_name.all()(对应SubCategory模型的related_name="category_name")
2. 优化查询性能(可选但推荐)
为避免模板中出现N+1查询问题,在视图中使用prefetch_related预加载关联数据:
def Home(request): sliders = Slider.objects.all() banners = BannerArea.objects.all() # 预加载分类和子分类,减少数据库查询次数 main_category = MainCategory.objects.prefetch_related('maincategory__category_name').all() context = { 'sliders' : sliders, 'banners' : banners, 'main_category' : main_category } return render(request, 'main/home.html', context)
修复后的模板代码
<div class="cat__menu"> <nav id="mobile-menu" style="display: block;"> <ul> {% for i in main_category %} <li> <a href="shop.html"> {{ i.name }} <i class="far fa-angle-down"></i></a> <ul class="mega-menu"> {% for cat in i.maincategory.all %} <li><a href="shop.html">{{cat.name}}</a> <ul class="mega-item"> {% for sub_cat in cat.category_name.all %} <li><a href="product-details.html">{{sub_cat.name}}</a></li> {% endfor %} </ul> </li> {% endfor %} </ul> </li> {% endfor %} </ul> </nav> </div>
内容的提问来源于stack exchange,提问作者user21878286
相关产品推荐
相关产品推荐

