Python/Django 传递给模板引擎的通用方法

Python/Django universal method passed to template engine

我有一个已经有数百个视图的大型 Django 项目。我正在创建一个 tasks 功能,用户可以在其中完成与他们正在使用的项目中的特定应用程序相关的特定任务。我有多个界面(又名项目中的 Django 应用程序):adminmanagementonsite 等...并且每个界面都有自己的导航 tasks link.

我想要的是能够在用户处于 task 尚未完成的界面时更改此 link 的颜色。

这很容易在每个视图中检查,然后我可以根据传递到视图中的变量为 link 普遍渲染正确的颜色,但这非常乏味,有数百个浏览量。

我想我可以在每个 interface/Django 应用程序中添加一个过滤器来稍微简化一下,但这是最简单的解决方案吗?

以下是我希望在每个界面的导航中调用的方法示例:

from objects_client.task_models.task_models import Tasks


def does_interface_have_open_tasks(current_interface, db_alias):
    if Tasks.objects.using(db_alias)\
            .filter(interface=current_interface, completed=0).exists():
        return True
    return False

我最终使用 Context Processor 来解决我的需求,如下所示:

import traceback
from objects_client.task_models.task_models import Tasks


def universally_used_data(request):
    # I use multiple DBs
    db_alias = request.session.get('db_alias')

    # dictionary for global context values
    dictionary_to_return = dict()

    # interfaces and URL equivalents
    interface_dictionary = {
        'adm': 'admin',
        'mgt': 'management',
        'onsite': 'onsite',
        'secu': 'security',
        'maint': 'maintenance'
    }

    try:
        # get interface url
        short_url = request.path[1:-1].split('/')[1]
        # get interface from dictionary above
        interface = interface_dictionary.get(short_url)

        dictionary_to_return['SHORT_URL'] = short_url

        dictionary_to_return['INTERFACE'] = interface

        # see if there is an open task...
        if Tasks.objects.using(db_alias) \
                .filter(interface=interface, completed=0).exists():

            dictionary_to_return['OPEN_TASKS'] = True
        else:
            dictionary_to_return['OPEN_TASKS'] = False

    except Exception as ex:
        print(ex, traceback.format_exc())

    return dictionary_to_return


这是我如何加载 Context Processor:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
            ... 
        ]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
               ... 
                # custom processors
                'utils.context_processors.context_processors.universally_used_data'
            ],
        },
    },
]

然后我可以像这样在模板中调用 this 变量来更改 HTML 元素的颜色,而不是 {% load [whatever] %} 或任何东西:

{% if OPEN_TASKS %}
    style="color:red;"
{% endif %}

感谢 @Daniel Roseman suggestion/comment。这让我有点难过:)