我有一个渲染模板的通用Django视图。该模板位于其他项目将使用的应用程序中。导入项目通常会为应用程序提供的View提供子类。 View有一个默认模板,它使用通用的措辞来完成工作。
99%的时间,子类化视图只想更改文本,所以为了改变非标记的措辞而不是让它们复制模板,我正在寻找一种方法来允许用户以最有效的方式替换模板中的措辞的类。
到目前为止探讨的选项:
template_strings
方法,它提供字符串的dict,最终在模板上下文中,子类可以覆盖template_strings
,但这看起来很糟糕,因为它可能会因为很多英文字符串而非常不合适。如果这样做,我会创建一个类似上下文的设置,这样你就不必重新声明所有字符串似乎应该是一个解决的问题,以创建一个完整的工作并只为文本提供备用字符串的视图。有比上面更好的方法吗?惯例?我错过了什么?
(django 1.11 Python 3.6.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()填充上下文。
至少要清楚哪些字符串可以为扩展基类的用户覆盖,并且不会干扰翻译。