¿Cómo uso las plantillas de Django sin el resto de Django?

101

Quiero usar el motor de plantillas Django en mi código (Python), pero no estoy creando un sitio web basado en Django. ¿Cómo lo uso sin tener un archivo settings.py (y otros) y tener que configurar la variable de entorno DJANGO_SETTINGS_MODULE?

Si ejecuto el siguiente código:

>>> import django.template
>>> from django.template import Template, Context
>>> t = Template('My name is {{ my_name }}.')

Yo obtengo:

ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
Daryl Spitzer
fuente

Respuestas:

133

La solucion es simple. En realidad, está bien documentado , pero no es demasiado fácil de encontrar. (Tuve que investigar, no surgió cuando probé algunas búsquedas diferentes en Google).

El siguiente código funciona:

>>> from django.template import Template, Context
>>> from django.conf import settings
>>> settings.configure()
>>> t = Template('My name is {{ my_name }}.')
>>> c = Context({'my_name': 'Daryl Spitzer'})
>>> t.render(c)
u'My name is Daryl Spitzer.'

Consulte la documentación de Django (vinculada anteriormente) para obtener una descripción de algunas de las configuraciones que puede querer definir (como argumentos de palabras clave para configurar).

Daryl Spitzer
fuente
13
Y para obtenerlo de un archivo: settings.configure (TEMPLATE_DIRS = (".",)) T = get_template ('test.html')
Bryce
La documentación para settings.configure () está aquí - docs.djangoproject.com/en/1.7/topics/settings
Scott
Desde el enlace "bien documentado" anterior, esto es cierto hasta la versión 1.7. A partir de 1.8, parece que ya no lo necesita settings.configure().
Olaf Dietsche
Si desea incluir otras plantillas o utilizar la herencia de plantillas, es necesaria la solución anterior de Bryce.
titusjan
6
Además, necesitaba llamar a django.setup () antes del constructor de plantillas.
Amit
44

La sintaxis de Jinja2 es prácticamente la misma que la de Django con muy pocas diferencias, y obtienes un motor de plantillas mucho más poderoso, que también compila tu plantilla en código de bytes (¡RÁPIDO!).

Lo uso para crear plantillas, incluso en Django, y es muy bueno. También puede escribir extensiones fácilmente si falta alguna característica que desee.

Aquí hay una demostración de la generación de código:

>>> import jinja2
>>> print jinja2.Environment().compile('{% for row in data %}{{ row.name | upper }}{% endfor %}', raw=True) 
from __future__ import division
from jinja2.runtime import LoopContext, Context, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join
name = None

def root(context, environment=environment):
    l_data = context.resolve('data')
    t_1 = environment.filters['upper']
    if 0: yield None
    for l_row in l_data:
        if 0: yield None
        yield unicode(t_1(environment.getattr(l_row, 'name')))

blocks = {}
debug_info = '1=9'
nosklo
fuente
4
Estoy usando Jinja en un proyecto mío, porque quería algo con lo que estuviera bastante familiarizado, pero no quería que mis usuarios (ya que es una aplicación distribuible) tuvieran que instalar Django. Una ventaja es que Jinja se puede instalar con easy_install.
Xiong Chiamiov
4
Django también se puede instalar con easy_install.
hegemon
Jinga no es oficialmente compatible con Python3 todavía. Según el sitio, todavía es experimental.
Pramod
9

¿Alguna razón en particular por la que desea utilizar las plantillas de Django? Tanto Jinja como Genshi son, en mi opinión, superiores.


Si realmente lo desea, consulte la documentación de Django ensettings.py . Especialmente la sección "Uso de la configuración sin configurar DJANGO_SETTINGS_MODULE". Usa algo como esto:

from django.conf import settings
settings.configure (FOO='bar') # Your settings go here
John Millikin
fuente
7

También recomendaría jinja2. Hay un buen artículo sobre djangovs. jinja2que brinda información detallada sobre por qué debería preferir la última.

olt
fuente
Prefiero Jinja2 debido a la {% set %}sintaxis y la igualdad con el motor de plantillas Twig (PHP). Es mejor escribir código multiplataforma siempre, pero la diferencia de rendimiento no es crítica; por ejemplo, Python siempre funcionará más lento que PHP, por lo que si necesita rendimiento, es mejor que cree un sitio con PHP, Twig y Symfony2 o más. Triste pero verdad.
Croll
@Croll, si su sitio web realiza cálculos complejos, las bibliotecas de Python son incomparablemente más rápidas; de lo contrario, el cuello de botella es la base de datos o es probable que esté haciendo algo realmente mal
Bob
4

Según la documentación de Jinja, la compatibilidad con Python 3 aún es experimental . Entonces, si está en Python 3 y el rendimiento no es un problema, puede usar el motor de plantillas integrado de django.

Django 1.8 introdujo soporte para múltiples motores de plantillas, lo que requiere un cambio en la forma en que se inicializan las plantillas. Debe configurar explícitamente settings.DEBUGcuál es el que usa el motor de plantilla predeterminado proporcionado por django. Aquí está el código para usar plantillas sin usar el resto de django.

from django.template import Template, Context
from django.template.engine import Engine

from django.conf import settings
settings.configure(DEBUG=False)

template_string = "Hello {{ name }}"
template = Template(template_string, engine=Engine())
context = Context({"name": "world"})
output = template.render(context) #"hello world"
Pramod
fuente
4

Además de lo que otros escribieron, si quieres usar Django Template en Django> 1.7, debes darle a tu settings.configure (...) llamar a la variable TEMPLATES y llamar a django.setup () así:

from django.conf import settings

settings.configure(TEMPLATES=[
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['.'], # if you want the templates from a file
        'APP_DIRS': False, # we have no apps
    },
])

import django
django.setup()

Luego puede cargar su plantilla como normalmente, desde una cadena:

from django import template   
t = template.Template('My name is {{ name }}.')   
c = template.Context({'name': 'Rob'})   
t.render(c)

Y si escribió la variable DIRS en .configure, desde el disco:

from django.template.loader import get_template
t = get_template('a.html')
t.render({'name': 5})

Error de Django: no se ha configurado ningún backend de DjangoTemplates

http://django.readthedocs.io/en/latest/releases/1.7.html#standalone-scripts

Robert Vanden Eynde
fuente
2

Yo diría que también Jinja . Definitivamente es más poderoso que Django Templating Engine y es independiente .

Si se trataba de un complemento externo para una aplicación Django existente, podría crear un comando personalizado y usar el motor de plantillas dentro de su entorno de proyectos. Me gusta esto;

manage.py generatereports --format=html

Pero no creo que valga la pena usar el motor de plantillas Django en lugar de Jinja.

muhuk
fuente
2

Gracias por la ayuda, amigos. Aquí hay una adición más. El caso en el que necesita utilizar etiquetas de plantilla personalizadas.

Digamos que tiene esta etiqueta de plantilla importante en el módulo read.py

from django import template

register = template.Library()

@register.filter(name='bracewrap')
def bracewrap(value):
    return "{" + value + "}"

Este es el archivo de plantilla html "temp.html":

{{var|bracewrap}}

Finalmente, aquí hay un script de Python que se vinculará a todos juntos

import django
from django.conf import settings
from django.template import Template, Context
import os

#load your tags
from django.template.loader import get_template
django.template.base.add_to_builtins("read")

# You need to configure Django a bit
settings.configure(
    TEMPLATE_DIRS=(os.path.dirname(os.path.realpath(__file__)), ),
)

#or it could be in python
#t = Template('My name is {{ my_name }}.')
c = Context({'var': 'stackoverflow.com rox'})

template = get_template("temp.html")
# Prepare context ....
print template.render(c)

La salida sería

{stackoverflow.com rox}
Gourneau
fuente
django.template.base.add_to_builtins("read")plantea un ValueErrorpara mí.
remo
da TemplateDoesNotExisterror Estoy usando django 1.10.1
Vikrant Singh
1

No lo hagas. Use StringTemplate en su lugar; no hay razón para considerar ningún otro motor de plantilla una vez que lo sepa.

Rob Williams
fuente
El puerto de Python se parece demasiado a Java. No es pitónico.
Michael Buckley
0

Hago eco de las declaraciones anteriores. Jinja 2 es un superconjunto bastante bueno de plantillas de Django para uso general. Creo que están trabajando para hacer que las plantillas de Django estén un poco menos acopladas a settings.py, pero Jinja debería funcionar bien para ti.

Clint Ecker
fuente
0

Mientras ejecuta el manage.pyshell:

>>> from django import template   
>>> t = template.Template('My name is {{ me }}.')   
>>> c = template.Context({'me': 'ShuJi'})   
>>> t.render(c)
hupantingxue
fuente
0

Google AppEngineusa el motor de plantillas Django, ¿has echado un vistazo a cómo lo hacen? Posiblemente podrías usar eso.

William Keller
fuente