为所有视图提供额外的上下文

Posted

技术标签:

【中文标题】为所有视图提供额外的上下文【英文标题】:Provide extra context to all views 【发布时间】:2021-11-20 05:38:45 【问题描述】:

我正在使用 django 为我的团队构建一个项目管理网站。我的基本模板包括一个侧边栏菜单,其中包含所有项目和用户的列表,分别链接到该用户或项目的 DetailView

我的问题是我需要为每个视图提供UserProject 模型,以便我可以渲染那个侧边栏。我知道怎么add extra context;问题是我觉得我通过修改每个级别的上下文来违反 DRY。是否可以简单地重新定义基础 TemplateClass 以便所有子类(ListViewDetailView 等)包含修改后的上下文?

在相关说明中,如果这是一种糟糕的项目设置方式,请告诉我。

【问题讨论】:

【参考方案1】:

你可以使用template context processor:

myapp/context_processors.py:

from django.contrib.auth.models import User
from myapp.models import Project

def users_and_projects(request):
    return 'all_users': User.objects.all(),
            'all_projects': Project.objects.all()

然后将此处理器添加到 Django 版本 TEMPLATE_CONTEXT_PROCESSORS 设置:

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'myapp.context_processors.users_and_projects',
)

对于 Django 版本 >= 1.8 将其添加到 TEMPLATES 设置的 OPTIONS 中的 context_processors 列表中:

TEMPLATES = [
    
        ...
        'OPTIONS': 
            'context_processors': [
                ...
                'myapp.context_processors.users_and_projects',
            ],
        ,
    ,
]

上下文处理器将为您的所有请求运行。如果您只想为使用base.html 渲染的视图运行这些查询,那么另一个可能的解决方案是custom assignment tag:

@register.assignment_tag
def get_all_users():
    return User.objects.all()

@register.assignment_tag
def get_all_projects():
    return Project.objects.all()

在您的base.html 模板中:

% load mytags %

% get_all_users as all_users %
<ul>
% for u in all_users %
    <li><a href=" u.get_absolute_url "> u </a></li>
% endfor %
</ul>

% get_all_projects as all_projects %
<ul>
% for p in all_projects %
    <li><a href=" p.get_absolute_url "> p </a></li>
% endfor %
</ul>

【讨论】:

哇,真快。谢谢!只是为了增加完整性:link to the django docs discussing writing your own template context processors. 感谢您的更新。我更改了答案中的第一个链接。 从 Django 1.8 开始,上下文处理器被添加到 TEMPLATES setting TEMPLATES = [ 'OPTIONS': 'context_processors': [...] ] 从 Django 1.9 开始,assignment_tag is deprecated and needs to be replaced with simple_tag。所以,你应该使用@register.simple_tag,而不是@register.assignment_tag @DerekPK 它适用于您项目中的所有应用程序,它是用myapp 编写的,因为代码必须存在于某处对吗?

以上是关于为所有视图提供额外的上下文的主要内容,如果未能解决你的问题,请参考以下文章

QT 模型/视图编程:我应该如何检索上下文菜单选项的额外数据?

SwiftUI:contextMenu 菜单

我应该如何在函数视图中调用基于类的通用视图

上下文管理器的重写以计算术运算对应的魔术方法

创建一个 Drupal 视图,加载共享任何一个分类术语的所有文章(上下文过滤器)

将上下文添加到每个 Django 管理页面