Django类视图中如何通过Category ID获取分类标题并传递到模板
在Django产品列表页展示对应分类标题的解决方案
问题场景
我有category和product两个模型,首页展示多个分类,点击任意分类后跳转至对应分类的产品列表页。已经通过URL将cat_id传递至products(ListView)视图,但需要借助cat_id获取对应分类的title,在产品列表页顶部展示该标题。
模型代码
class category(models.Model): title = models.CharField(max_length=30) image = models.ImageField(null=True, blank=True) def __str__(self): return self.title class product(models.Model): name = models.CharField(max_length=50, null=True, blank=True) slug = models.SlugField(null=True, blank=True) description = models.TextField(max_length=500, null=True, blank=True) category = models.ForeignKey(category, on_delete=models.CASCADE) cost = models.PositiveIntegerField() image = models.ImageField(null=True, blank=True) def save(self, *args, **kwargs): self.slug = slugify(self.name) return super().save(*args, **kwargs) def __str__(self): return self.name
当前视图代码(仅传入cat_id)
class products(ListView): model = product template_name = 'products/productList.html' context_object_name = 'products' def get_context_data(self, **kwargs): context = super(products, self).get_context_data(**kwargs) context['category'] = self.kwargs['cat_id'] return context
URL配置
path('<int:cat_id>', products.as_view(), name='products'),
解决方案
方法一:直接查询分类对象并过滤产品
修改products视图,在get_queryset中过滤当前分类的产品,同时在get_context_data中查询对应的分类对象传入模板:
from django.views.generic import ListView from .models import product, category class products(ListView): model = product template_name = 'products/productList.html' context_object_name = 'products' def get_queryset(self): # 仅返回当前分类下的产品 cat_id = self.kwargs.get('cat_id') return product.objects.filter(category_id=cat_id) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) cat_id = self.kwargs.get('cat_id') # 获取对应分类对象,传入上下文 context['current_category'] = category.objects.get(id=cat_id) return context
在模板products/productList.html中,直接调用分类标题:
<h1>{{ current_category.title }}</h1> <!-- 下方展示产品列表 --> {% for product in products %} <!-- 产品内容 --> {% endfor %}
方法二:用通用视图组合(更规范,支持404处理)
通过SingleObjectMixin获取分类对象,再基于该对象过滤产品,同时自动处理分类不存在的情况:
from django.views.generic import ListView from django.views.generic.detail import SingleObjectMixin from .models import product, category from django.shortcuts import get_object_or_404 class products(SingleObjectMixin, ListView): model = product template_name = 'products/productList.html' context_object_name = 'products' single_object_model = category # 指定SingleObjectMixin对应的模型 def get(self, request, *args, **kwargs): # 获取分类对象,不存在则返回404页面 self.object = get_object_or_404(category, id=self.kwargs.get('cat_id')) return super().get(request, *args, **kwargs) def get_queryset(self): # 基于分类对象过滤产品 return product.objects.filter(category=self.object) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['current_category'] = self.object return context
模板使用方式和方法一完全一致。
额外建议
Django模型类名建议遵循PEP8规范,使用大驼峰命名(如Category、Product),这样代码可读性更高,也符合社区惯例。
内容的提问来源于stack exchange,提问作者shubdb
相关产品推荐
相关产品推荐

