首页 > 解决方案 > 带有变量的应用程序的 django 通用模板

问题描述

我想制作项目范围的模板,但使用应用程序变量和应用程序基础子模板:

/home/project/
              templates/document.html
              app1/templates/app1/base.html
              app2/templates/app2/base.html

和 app1/views.py:

def page1(request):
    document = get_document('title',app_email='test@example.com')
    context = {
            'document' : document,
            'app_title_header' : document.header
    }
    return render(request,'document.html', context)

模板/document.html

{% extends app_name|add:'/base.html' %}
{% load static %}

{% block content %}
      {% autoescape off %}
      {{ document.body }}
      {% endautoescape %}
{% endblock %}

(app_name 由在 settings.py 中注册的 context_processors.py 设置)

def appname(request):
    return {'app_name': request.host.name, 'app_base' : '{}/base.html'.format(request.host.name) }

app1/templates/app1/base.html(几乎与 app2 相同)

{% load static app1 %} <--- difference with app2
<!doctype html>
<html lang="pl">
  <head>
    <meta charset="utf-8">
   {% block head %}
    {% endblock %}
      <title>{% app_title %} - {{ app_title_header }}</title>

  {% include "app1/google.html" %}
  </head>

app1/templates/app1/google.html

{% load app1 %}
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id={% g_tag %}"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

gtag('config', '{% g_tag %}');
</script>

现在:

render 从项目/模板中获取 document.html。首先它扩展app_name了 /base.html - 所以它包括 google.html (Google Analytics)。

它有效。但是现在我想将 google.html 和 fb.html 移动到项目模板中,但是有唯一的 G_TAG,所以它必须是一个标签或某事。由于 google.html 中的 {% load app1 %},我不能只移动它。

我认为这太复杂了——我认为有简单的解决方案——但不知道该走哪条路。

最重要的限制 - 我不想使用应用程序中的 context_processors。我只将 context_processor 用于常见的事情,因为我在 app1 和 app2 中使用相同的变量,并且 context_processor 会覆盖它。

标签: djangodjango-templates

解决方案


(注:你可能正在遭受 DRY 迷恋~:))

您需要在某处硬编码值,无论是 ViewMixin 中的属性,从共享存储或模板文件中检索它 - 事情是,您已经到了共享功能与区分每个调用的变量一样微不足道的地步:您需要输出带有一些周围元素的变量的值。该变量需要来自某个地方,因此重复variable = value将以一种或另一种形式发生。

我的 2 美分...如果我对这个问题的理解不够好,请告诉我。

因此,如果这是在您的模板中:

<script async src="https://www.googletagmanager.com/gtag/js?id={{ g_tag }}"></script>

这是一个视图混合:

from django.views import generic
from centralapp.models import ConfigModel


class GoogleTagMixin(generic.base.ContextMixin):
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        app_config = ConfigModel.objects.get(host=self.request.get_host())
        context['g_tag'] = app_config.google_tag
        return context

然后你有一个模板,可以在任何你需要的视图中使用 mixin。

如果您不想要 mixin,您可以对中间件执行相同的操作并在请求对象上设置值。

我不确定你在寻找什么是“更好的”。


推荐阅读