Django:高效的模板/字符串分离和覆盖

时间:2017-08-12 18:53:18

标签: python django django-templates

我有一个渲染模板的通用Django视图。该模板位于其他项目将使用的应用程序中。导入项目通常会为应用程序提供的View提供子类。 View有一个默认模板,它使用通用的措辞来完成工作。

99%的时间,子类化视图只想更改文本,所以为了改变非标记的措辞而不是让它们复制模板,我正在寻找一种方法来允许用户以最有效的方式替换模板中的措辞的类。

到目前为止探讨的选项:

  • 模板部分仅包含使用应用程序可以覆盖的文本(魔术,大量用户工作)
  • 视图上的template_strings方法,它提供字符串的dict,最终在模板上下文中,子类可以覆盖
  • 使用(滥用?)翻译系统,以便应用程序提供默认的英语翻译,并使用代码可以提供自己的翻译(实际上还没有完成这个,只是一个想法)
  • 通过AppConfig执行上述template_strings,但这看起来很糟糕,因为它可能会因为很多英文字符串而非常不合适。如果这样做,我会创建一个类似上下文的设置,这样你就不必重新声明所有字符串

似乎应该是一个解决的问题,以创建一个完整的工作并只为文本提供备用字符串的视图。有比上面更好的方法吗?惯例?我错过了什么?

(django 1.11 Python 3.6.2)

2 个答案:

答案 0 :(得分:2)

您可以继承TemplateView或将ContextMixin添加到您的视图中,然后覆盖get_context_data函数,如下所示:

from django.views.generic import TemplateView

class BaseView(TemplateView):
    template_name = "common.html"

class SubView(BaseView):
    def get_context_data(self, **kwargs):
        context = super(SubView, self).get_context_data(**kwargs)
        context['content'] = "Some sub view text"
        return context

更新:使用模板覆盖

如果您想将文本分开,这是更好的方法 要允许跨应用轻松覆盖DRY模板,您可能需要安装此package(其他一些详细信息here

我们的定义与上面类似,但改为template_name代替:

from django.views.generic import TemplateView

    class BaseView(TemplateView):
        template_name = "main.html"

    # on another app
    class SubView(BaseView):
        template_name = "sub_view.html"

然后神奇的是你可以extends并覆盖block模板的BaseView,如下所示:

<强> base_app /模板/ main.html中

<p>I'm Common Text</p>
{% block main %}
  <p>I'm Base View</p>
{% endblock %}

<强> sub_app /模板/ sub_view.html

{% extends "base_app:main.html" %}
{% block main %}
  <p>I'm Sub View</p>
{% endblock %}

结果将是:

<p>I'm Common Text</p>
<p>I'm Sub View</p>

答案 1 :(得分:0)

Afaik你很好地介绍了这些选项。我的例子可能只是模板字符串的变体,但也许它有帮助...

class DefaultStringProvider():
    TITLE = 'Hello'
    DESCRIPTION = 'Original description'
    CATEGORY = 'Stuff'

class MyTemplateBaseView(TemplateView):
    def get_context_data(self, **kwargs):
        return super(MyTemplateBaseView, self).get_context_data(
            provider=self.get_string_provider(), **kwargs)

    def get_string_provider(self):
        return DefaultStringProvider()

class OtherView(MyTemplateBaseView):
    template_name = 'welcome.html'

    def get_string_provider(self):
        p = DefaultStringProvider()
        p.TITLE = 'Hello'
        p.DESCRIPTION = 'New description'
        return p

我们的想法是拥有一个默认的字符串提供程序,基本视图通过get_string_provider()填充上下文。

至少要清楚哪些字符串可以为扩展基类的用户覆盖,并且不会干扰翻译。