Django: эффективное разделение шаблонов/строк и переопределение
У меня есть общий вид Django, который отображает шаблон. Шаблон находится в приложении, которое будут использовать другие проекты. Импорт проектов обычно подклассифицируется в представлении "Просмотр приложения". В представлении есть шаблон по умолчанию, который выполняет задание с общей формулировкой.
99% времени, подклассирование Views будет хотеть только изменять текст, поэтому вместо того, чтобы заставить их дублировать шаблон для изменения формулировки без разметки, я ищу способ разрешить пользователям класса чтобы заменить формулировку в шаблоне наиболее эффективным способом.
Параметры, изученные до сих пор:
- частичные части шаблона, содержащие только текст, который может использовать приложения (магия, много работы пользователя)
- A
template_strings
на представлении, которое предоставляет бит строк, которые заканчиваются в контексте шаблона, которые подклассы могут переопределять
- Использование (злоупотребление?) системы перевода, так что приложение предоставляет английские переводы по умолчанию, а использование кода может обеспечить их собственные переводы вместо этого (на самом деле это не работало, а просто идея).
- Выполнение вышеприведенного
template_strings
через AppConfig, но это кажется... yucky, как будто это может стать очень неуязвимым с множеством английских строк. Если я это сделаю, я создам контекстно-подобную настройку, поэтому вам не нужно повторно объявлять все строки
Похоже, что проблема должна быть решена для подкласса представления, которое выполняет полную работу и просто предоставляет альтернативные строки для текста. Есть ли лучший способ, чем выше? Конвенция? Что-то мне не хватает?
(django 1.11 Python 3.6.2)
Ответы
Ответ 1
Вы можете либо наследовать 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
Обновление: использование переопределения шаблона
Если вы хотите отделить текст, это лучший способ пойти
Чтобы разрешить простой и суровый шаблон замены в приложениях, вам может потребоваться установить этот пакет (некоторые другие детали здесь)
Определим его так же, как указано выше, но вместо этого изменим 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>
Ответ 2
Афайк, вы хорошо изучили варианты. Мой пример, вероятно, всего лишь вариант строк шаблона, но, возможно, он все равно помогает...
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().
По крайней мере будет ясно, какие строки можно переопределить для пользователя, расширяющего базовый класс, и он не будет мешать переводам.