Django单页展示多视图:如何为dashboard模板的include子页传递上下文数据
解决方案
你可以通过以下两种常用方案实现需求,两种方案都可以平滑适配你现有代码,学习成本低:
方案1:Dashboard视图聚合所有上下文(适合入门,逻辑最直观)
单个视图可以传递任意数量的上下文变量,所有被include引入的子模板都可以直接读取父模板的上下文变量,你只需要给Dashboard单独写一个视图,把所有模块需要的数据都放到context里即可:
步骤1:编写Dashboard视图
在你的views.py中新增如下代码:
# 先导入你需要展示的所有模型 from .models import Event # 如果你还要展示其他模块数据,继续导入对应模型即可,比如 from .models import Order, User def dashboard(request): context = { # 活动列表数据,对应event_list.html需要的变量名 "event_list": Event.objects.all(), # 其他模块需要的数据在这里追加即可 # "order_list": Order.objects.filter(status="已完成"), # "total_user": User.objects.count() } # 渲染你的dashboard模板,传入聚合好的上下文 return render(request, "你的dashboard模板路径.html", context)
步骤2:绑定Dashboard路由
在你的urls.py中新增路由映射:
from . import views urlpatterns = [ # 其他原有路由 path("dashboard/", views.dashboard, name="dashboard"), ]
配置完成后,你原来模板里的{% include 'pages/event_list.html' %}可以直接正常读取到event_list数据,不需要做其他修改。
方案2:自定义inclusion tag(可复用性更高,适合多页面共用模块场景)
如果后续你需要在多个页面都插入活动列表、订单列表这类模块,每个视图都重复加上下文变量会很冗余,你可以用Django的自定义inclusion tag实现模块逻辑和数据的封装,一次编写到处调用。
步骤1:创建标签文件
在你的APP目录下新建templatetags文件夹,文件夹内新增两个文件:
- 空文件
__init__.py - 代码文件
dashboard_tags.py
步骤2:编写inclusion tag
在dashboard_tags.py中写入如下代码:
from django import template from ..models import Event register = template.Library() # 绑定该标签要渲染的子模板 @register.inclusion_tag("pages/event_list.html") def show_event_list(): # 在这里写你原来的查询逻辑,返回子模板需要的上下文 event_list = Event.objects.all() return {"event_list": event_list} # 其他要复用的模块都可以按照这个格式新增,比如 # @register.inclusion_tag("pages/order_list.html") # def show_order_list(): # order_list = Order.objects.all() # return {"order_list": order_list}
步骤3:模板中调用标签
修改你的Dashboard模板:
- 在模板最顶部(
{% extends %}之后)加载你写的标签:{% load dashboard_tags %} - 把原来的
{% include 'pages/event_list.html' %}替换为{% show_event_list %}
之后任何页面需要插入活动列表,只要加载dashboard_tags后调用{% show_event_list %}即可,不需要在对应视图中额外传数据。
扩展:带参数的标签
如果你的数据需要根据当前用户、请求参数过滤,可以开启上下文传递:
# takes_context=True表示可以拿到父模板的上下文 @register.inclusion_tag("pages/event_list.html", takes_context=True) def show_user_event_list(context): # 从上下文中拿到request对象 request = context["request"] # 只查询当前用户创建的活动 event_list = Event.objects.filter(creator=request.user) return {"event_list": event_list}
内容的提问来源于stack exchange,提问作者JacksWastedLife
相关产品推荐
相关产品推荐

