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

如何在Django中高效提取多个视图的通用上下文?

提取Django视图通用上下文变量的方案

假设我们有两个或多个视图,每个视图的模板都继承自base.html,且base.html文件中包含上下文变量project_name和company_name:

文件 base.html

<!DOCTYPE html>
<html>
  <head>
    <title>{{ project_name }}</title>
  </head>
  <body>
    {{ company_name }}
    {% block content %}{% endblock %}
  </body>
</html>

当前我们需要在每个视图中重复添加这两个通用上下文变量,代码如下:

文件 views.py

def view1(request):
    context = {
        "view1 data": "some data",
        "project_name": "Project Name",
        "company_name": "Company Name",
    }
    return render(request, "view1.html", context)


class View2(DetailView):
    template_name = "view2.html"
    model = SampleModel

    def get_context_data(self, **kwargs):
        context = super(View2, self).get_context_data(**kwargs)
        context["view2 data"] = "sample data"
        context["project_name"] = "Project Name"
        context["company_name"] = "Company Name"
        return context

我们需要优化代码,将project_name和company_name这两个通用上下文提取到其他位置,同时让base.html仍能正常获取这些变量,最终视图代码如下:

期望的views.py

def view1(request):
    context = {
        "view1 data": "some data",
    }
    return render(request, "view1.html", context)


class View2(DetailView):
    template_name = "view2.html"
    model = SampleModel

    def get_context_data(self, **kwargs):
        context = super(View2, self).get_context_data(**kwargs)
        context["view2 data"] = "sample data"
        return context

由于基于函数的视图(FBV)和基于类的视图(CBV)工作机制不同,下面提供几种针对性的解决方案:


方案一:全局上下文处理器(推荐,同时支持FBV和CBV)

Django的上下文处理器可以全局注入通用变量,所有模板都能直接访问:

  1. 在你的应用目录下创建context_processors.py文件,编写通用上下文函数:
def common_context(request):
    return {
        "project_name": "Project Name",
        "company_name": "Company Name"
    }
  1. 在项目的settings.py中,找到TEMPLATES配置,将上述处理器添加到context_processors列表:
TEMPLATES = [
    {
        # 保留原有配置项...
        'OPTIONS': {
            'context_processors': [
                # 原有处理器(比如django.contrib.auth.context_processors.auth等)
                'your_app_name.context_processors.common_context',
            ],
        },
    },
]

配置完成后,所有视图对应的模板都能直接使用project_name和company_name,无需在视图中重复定义。


方案二:针对FBV的自定义渲染函数

如果不想全局注入,可封装一个包含通用上下文的自定义渲染函数:

from django.shortcuts import render

def custom_render(request, template_name, context=None):
    # 定义通用上下文
    common_ctx = {
        "project_name": "Project Name",
        "company_name": "Company Name"
    }
    # 合并视图自定义上下文
    if context:
        common_ctx.update(context)
    return render(request, template_name, common_ctx)

然后在FBV中使用这个函数替代原生render:

def view1(request):
    context = {
        "view1 data": "some data",
    }
    return custom_render(request, "view1.html", context)

方案三:针对CBV的Mixin类

对于CBV,可通过编写Mixin类来复用通用上下文逻辑:

from django.views.generic.detail import DetailView

class CommonContextMixin:
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 添加通用上下文
        context.update({
            "project_name": "Project Name",
            "company_name": "Company Name"
        })
        return context

让你的CBV继承这个Mixin(注意Mixin要放在视图基类之前):

class View2(CommonContextMixin, DetailView):
    template_name = "view2.html"
    model = SampleModel

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["view2 data"] = "sample data"
        return context

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 19:18:36