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

Django REST Framework多页复用HTML加载对应分类数据

Django DRF 多分类页面复用单模板+单库实现方案

问题根源

现有实现未给商品绑定分类属性,视图层全量拉取商品数据,同时为每个分类单独编写重复视图和模板,最终导致数据无法隔离、代码冗余度高。

分步实现

1. 给商品模型新增分类字段

首先修改models.py中的Product模型,新增分类标识字段用于后续数据筛选,不需要新建数据库表:

from django.db import models

class Product(models.Model):
    # 保留原有字段
    image = models.ImageField(upload_to='products/')
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    buy = models.CharField(max_length=200)
    # 新增分类slug字段,值和URL路径对齐,比如home、foods、drinks等,加索引提升查询效率
    category = models.SlugField(max_length=50, db_index=True)

修改完成后依次执行python manage.py makemigrations、python manage.py migrate完成表结构更新。

2. 改造视图层,单视图处理全部分类页面

删除原有重复的home、foods视图函数,只编写一个通用分类视图,根据URL传入的分类参数筛选对应数据,统一传给同一个模板。
修改views.py:

from django.shortcuts import render, get_object_or_404
from .models import Product
from rest_framework.viewsets import ModelViewSet
from .serializers import ProductSerializer
from django_filters.rest_framework import DjangoFilterBackend

# 可维护的分类配置,后续新增分类直接在这里追加即可,无需修改视图、模板、路由
CATEGORY_MAP = {
    'home': '首页推荐',
    'foods': '食品专区',
    # 后续扩展到20个分类时,只需要在这里追加键值对,key对应URL路径,value对应页面显示名称
}

def product_category_view(request, category):
    # 校验分类合法性,非法分类直接返回404
    if category not in CATEGORY_MAP:
        raise get_object_or_404
    # 仅拉取当前分类下的商品,不再全量查询
    product_list = Product.objects.filter(category=category)
    context = {
        'p': product_list, # 保持原有模板变量名不变,减少模板修改成本
        'current_category': category,
        'current_category_name': CATEGORY_MAP[category]
    }
    return render(request, 'product_list.html', context)

class ProductViewSet(ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    # 新增过滤配置,支持接口按category参数筛选对应分类数据
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['category']

注:如果未安装django-filter,先执行pip install django-filter,再把django_filters添加到settings.py的INSTALLED_APPS列表中即可。

3. 配置URL路由,无需为每个分类单独写路由

修改app下的urls.py,用动态参数匹配所有分类页面:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register(r'products', views.ProductViewSet)

urlpatterns = [
    # 首页默认指向home分类
    path('', views.product_category_view, {'category': 'home'}, name='home'),
    # 动态匹配所有分类页面,比如访问 /products/foods/ 即可进入食品专区
    path('products/<slug:category>/', views.product_category_view, name='product_category'),
    # DRF接口路由
    path('api/', include(router.urls)),
]

4. 合并模板,单模板复用全部分类页面

删除原有重复的home.html、foods.html,新建统一的product_list.html模板,原有卡片遍历逻辑完全保留,仅把页面标题等动态内容替换为传入的分类变量即可:

<!DOCTYPE html>
<html>
<head>
    <title>{{ current_category_name }}</title>
</head>
<body>
    <h1>{{ current_category_name }}</h1>
    <div class="product-list">
        {% for item in p %}
        <div class="product-card">
            <img src="{{ item.image.url }}" alt="{{ item.description }}">
            <p>{{ item.description }}</p>
            <p>¥{{ item.price }}</p>
            <button>{{ item.buy }}</button>
        </div>
        {% empty %}
        <!-- 分类下无数据时显示空提示,不会再渲染其他分类的卡片 -->
        <p>当前分类暂无商品</p>
        {% endfor %}
    </div>
</body>
</html>

扩展说明

  • 新增分类时,仅需在CATEGORY_MAP中追加对应的分类键值对,不需要新增视图、模板、路由,也不需要新建数据库
  • 新增商品时,提交的JSON数据中带上category字段指定商品所属分类,商品就会自动在对应分类页面展示
  • 前端异步加载数据时,接口请求带上?category=分类标识参数即可拿到对应分类的商品数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 11:09:27