【问题标题】:django common templates for apps with variables带有变量的应用程序的 django 通用模板
【发布时间】:2021-04-03 11:40:49
【问题描述】:

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

/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 会覆盖它。

【问题讨论】:

  • 将 g_tag 存储在模型中(可能包含更多这些变量)并根据请求通过中间件设置 g_tag。
  • @Melvyn 但 g_tag 与 app 相关联...每个 app 都应该有自己的 g_tag 你认为为每个 app 创建相同的模型吗?很多余
  • 您没有共享应用程序?我的意思是,每个应用程序都可以从共享应用程序“api_tokens”或其他任何东西中获取价值。只是意味着每个应用程序都依赖于那个应用程序,就像每个应用程序都依赖于 Django。但是他们需要一些方法来注册自己的主机名,比如通过站点框架或等效的,以便中间件可以设置正确的值。
  • 或者我理解错了。您是否在一个项目中有多个应用程序,并且希望将渲染逻辑存储在一个模板中,并且每个应用程序都应该提供自己的值?
  • @Melvyn 只是一个模板,但每个应用程序都有自己的值

标签: django django-templates


【解决方案1】:

(注意:你可能正在遭受 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,你可以对中间件做同样的事情,并在请求对象上设置值。

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

【讨论】:

  • 我的应用非常相似,但在不同的领域。所以我想尽可能多地使用通用模板。但是有些值是硬编码的,例如每个应用程序都有自己的 g_tag。
  • 因此,如果它们在一个安装中但主机名不同,则使用站点框架(或类似 django-hosts)来创建或使用具有每个站点配置的模型。然后,您可以在视图中获取该值并将其作为众所周知的变量传递给模板。
  • django-hosts 绝对是,但它不会干扰模板。
  • 我不确定是否需要网站,因为模型没有问题(但 :D)我想让模板尽可能通用...
  • 这个 GoogleTagMixin 应该在哪个文件/文件夹中?以及如何使用它?
猜你喜欢
  • 2014-04-13
  • 2020-07-23
  • 2018-11-17
  • 1970-01-01
  • 1970-01-01
  • 2017-03-07
  • 1970-01-01
  • 2013-06-11
  • 2017-04-26
相关资源
最近更新 更多