Eu quero usar o mesmo {% block%} duas vezes no mesmo modelo de django. Quero que esse bloco apareça mais de uma vez no meu modelo base:
# base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
<h1>{% block title %}My Cool Website{% endblock %}</h1>
</body>
</html>
E depois estenda-o:
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
Eu receberei uma exceção, pois o Django deseja que o bloco apareça apenas uma vez:
TemplateSyntaxError em /
A tag 'block' com o nome 'title' aparece mais de uma vez
Uma solução rápida e suja seria duplicar o título do bloco em title1 e title2 :
# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}
Mas isso é uma violação do princípio DRY . Seria muito difícil, pois tenho muitos modelos herdados e também porque não quero ir para o inferno ;-)
Existe algum truque ou solução alternativa para esse problema? Como posso repetir o mesmo bloco no meu modelo, sem duplicar todo o código?
django
django-templates
dry
David Arcos
fonte
fonte
Respostas:
Eu acho que o uso do processador de contexto é, neste caso, um exagero. Você pode fazer isso facilmente:
e depois:
e assim por diante ... Parece compatível com DRY.
fonte
h1
conteúdo dentro do bloco que define o arquivotitle
. Ou um bloco que define uma parte dotitle
.Use o plug-in de macros de modelo do Django:
https://gist.github.com/1715202 (django> = 1.4)
ou
http://www.djangosnippets.org/snippets/363/ (django <1.4)
django> = 1.4
e
django <1.4
e
fonte
Você provavelmente não quer usar um bloco, mas apenas usar uma variável:
Você define o título pelo contexto.
fonte
Aqui está uma maneira que eu descobri ao tentar fazer a mesma coisa:
Infelizmente, requer um arquivo extra, mas não exige que você passe o título da visualização.
fonte
<tr>
briga era bastante complexa.você pode usar
{% include subtemplate.html %}
mais de uma vez. não é o mesmo que blocos, mas faz o truque.fonte
include
é mais lento queblock
. docs.djangoproject.com/en/1.10/topics/performance/…Há alguma discussão aqui: http://code.djangoproject.com/ticket/4529 Obviamente, a equipe principal do django rejeita esse ticket porque acha que esse não é um cenário usado comum, mas eu discordo.
O bloco de repetição é uma implementação simples e limpa para isso: https://github.com/SmileyChris/django-repeatblock
macros de modelo é outra, no entanto, o autor mencionou que não foi testado com cuidado: http://www.djangosnippets.org/snippets/363/
Eu usei o repeatblock.
fonte
Como uma atualização para quem se deparar com isso, peguei o trecho mencionado acima e o transformei em uma biblioteca de tags de modelo, django-macros, torna as macros mais poderosas e também implementa explicitamente um padrão de bloco repetido: django-macros .
fonte
Aqui está uma solução leve semelhante à resposta acima
do_set
e àdo_get
tag de modelo. O Django permite que você passe todo o contexto do modelo para uma tag, o que permite definir uma variável global.base.html:
page.html:
tag personalizada (teve a ideia aqui: https://stackoverflow.com/a/33564990/2747924 ):
Além disso, não se esqueça das
{% load %}
tags personalizadas ou adicione-as à lista de opções internas do modelo, para que você não precise carregá-las em todos os modelos. A única limitação a essa abordagem é a necessidade{% define %}
de ser chamada de dentro de uma tag de bloco, porque os modelos filhos processam apenas tags de bloco que correspondem às tags pai. Não tenho certeza se existe uma maneira de contornar isso. Certifique-se também de que adefine
chamada é recebida antes de tentar usá-la obviamente.fonte
Com base na sugestão de Van Gale, você pode criar tags get e set adicionando o seguinte ao seu arquivo templatetags.py:
Em seguida, defina valores em um modelo
{% set foo %}put data here{% endset %}
e obtenha-os{% get foo %}
em outro.fonte
Eu também encontrei a mesma necessidade de repetir {% block%} nos meus arquivos de modelo. O problema é que eu quero que um Django {% block%} seja usado nos dois casos de uma condição condicional do Django, e quero que o {% block%} seja sobrescrito pelos arquivos subseqüentes que podem estender o arquivo atual. (Portanto, nesse caso, o que eu quero é definitivamente mais um bloco do que uma variável, porque eu não estou tecnicamente reutilizando, apenas aparece nas duas extremidades de uma condicional.
O problema:
O código de modelo do Django a seguir resultará em um erro de sintaxe de modelo, mas acho que é um "desejo" válido ter um {% block%} definido reutilizado em uma condicional (IE, por que o analisador Django está validando a sintaxe em AMBOS OS TERMOS condicional, não deveria apenas validar a condição TRUTHY?)
A solução:
Você pode usar um {% include%} para inserir condicionalmente um {% block%} mais de uma vez. Isso funcionou para mim porque o verificador de sintaxe do Django inclui apenas o TRUTHY {% include%}. Veja o resultado abaixo:
fonte
Eu uso essa resposta para manter as coisas secas.
fonte
Existem duas soluções fáceis para isso.
O mais fácil é colocar seu título em uma variável de contexto. Você definiria a variável de contexto em sua exibição.
Se você estiver usando algo como visualizações genéricas e não tiver um views.py para fotos, gatos etc., poderá seguir o caminho de uma tag de modelo personalizada que define uma variável no contexto .
Seguir essa rota permitiria fazer algo como:
Em seguida, no seu base.html:
fonte
Any variable set in the context will only be available in the same block of the template in which it was assigned. This behavior is intentional; it provides a scope for variables so that they don’t conflict with context in other blocks.
A resposta selecionada faz alusão a uma solução fácil para quebrar uma marca dentro de outra no modelo filho para fornecer a ambos o mesmo valor. Eu uso isso para imagens sociais como essa.
Modelo filho:
Então no pai
base.html
:fonte
No galho, você pode fazer assim:
fonte