Como faço para usar modelos Django sem o resto do Django?

101

Quero usar o mecanismo de modelo Django em meu código (Python), mas não estou construindo um site baseado em Django. Como faço para usá-lo sem ter um arquivo settings.py (e outros) e ter que definir a variável de ambiente DJANGO_SETTINGS_MODULE?

Se eu executar o seguinte código:

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

Eu recebo:

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

Respostas:

133

A solução é simples. Na verdade, está bem documentado , mas não é muito fácil de encontrar. (Tive de pesquisar - não apareceu quando tentei algumas pesquisas diferentes no Google.)

O seguinte 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.'

Veja a documentação do Django (link acima) para uma descrição de algumas das configurações que você pode querer definir (como argumentos de palavra-chave para configurar).

Daryl Spitzer
fonte
13
E para obtê-lo de um arquivo: settings.configure (TEMPLATE_DIRS = (".",)) T = get_template ('test.html')
Bryce
A documentação para settings.configure () está aqui - docs.djangoproject.com/en/1.7/topics/settings
Scott
No link "bem documentado" acima, isso é verdade até a versão 1.7. A partir do 1.8, parece que você não precisa settings.configure()mais.
Olaf Dietsche de
Se você quiser incluir outros modelos ou usar herança de modelo, a solução acima de Bryce é necessária.
titusjan
6
Além disso, precisei chamar django.setup () antes do construtor de Template.
Amit
44

A sintaxe do Jinja2 é praticamente a mesma do Django, com poucas diferenças, e você obtém um mecanismo de template muito mais poderoso, que também compila seu template para bytecode (RÁPIDO!).

Eu o uso para modelagem, inclusive no próprio Django, e é muito bom. Você também pode escrever extensões facilmente se algum recurso desejado estiver faltando.

Aqui está uma demonstração da geração 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
fonte
4
Estou usando o Jinja em um projeto meu porque queria algo com o qual estivesse bastante familiarizado, mas não queria que meus usuários (já que é um aplicativo distribuível) tivessem que instalar o Django. Uma vantagem é que Jinja pode ser instalado com easy_install.
Xiong Chiamiov
4
Django pode ser instalado com easy_install também.
hegemon
Jinga não oferece suporte oficial para Python3 ainda. Segundo o site, ainda é experimental.
Pramod
9

Alguma razão em particular para usar os templates do Django? Tanto Jinja quanto Genshi são, na minha opinião, superiores.


Se você realmente quiser, consulte a documentaçãosettings.py do Django em . Especialmente a seção "Usando configurações sem configuração DJANGO_SETTINGS_MODULE". Use algo assim:

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

Eu também recomendaria jinja2. Há um bom artigo sobre djangovs. jinja2que fornece algumas informações detalhadas sobre por que você deve preferir o último.

olt
fonte
Eu prefiro Jinja2 por causa da {% set %}sintaxe e da igualdade do Twig template engine (PHP). É melhor escrever código de plataforma cruzada sempre, mas a diferença de desempenho não é crítica - por exemplo, python sempre funcionará mais devagar do que PHP, então se você precisa de desempenho é melhor criar um site com PHP, Twig e Symfony2 ou outro. Triste, mas é verdade.
Croll de
@Croll, se seu site realiza cálculos complexos, então as bibliotecas python são incomparavelmente mais rápidas, caso contrário, o gargalo é o banco de dados ou você provavelmente está fazendo algo realmente errado
Bob
4

De acordo com a documentação do Jinja, o suporte ao Python 3 ainda é experimental . Portanto, se você estiver no Python 3 e o desempenho não for um problema, você pode usar o mecanismo de modelo integrado do django.

Django 1.8 introduziu suporte para múltiplos motores de template que requerem uma mudança na forma como os templates são inicializados. Você tem que configurar explicitamente settings.DEBUGqual é usado pelo mecanismo de template padrão fornecido pelo django. Aqui está o código para usar modelos sem usar o resto do 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
fonte
4

Além do que outros escreveram, se você quiser usar Django Template no Django> 1.7, você deve fornecer seu settings.configure (...) chame a variável TEMPLATES e chame django.setup () assim:

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()

Então você pode carregar seu modelo normalmente, a partir de uma string:

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

E se você escreveu a variável DIRS no .configure, do disco:

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

Erro do Django: nenhum backend DjangoTemplates está configurado

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

Robert Vanden Eynde
fonte
2

Eu diria Jinja também. É definitivamente mais poderoso que o Django Templating Engine e é independente .

Se este fosse um plug externo para um aplicativo Django existente, você poderia criar um comando customizado e usar o mecanismo de modelagem dentro do ambiente de seus projetos. Como isso;

manage.py generatereports --format=html

Mas eu não acho que vale a pena usar o Django Templating Engine em vez do Jinja.

muhuk
fonte
2

Obrigado pela ajuda pessoal. Aqui está mais uma adição. O caso em que você precisa usar tags de modelo personalizado.

Digamos que você tenha esta importante tag de modelo no módulo read.py

from django import template

register = template.Library()

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

Este é o arquivo de modelo html "temp.html":

{{var|bracewrap}}

Finalmente, aqui está um script Python que se conectará a todos

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)

A saída seria

{stackoverflow.com rox}
Gourneau
fonte
django.template.base.add_to_builtins("read")levanta um ValueErrorpara mim.
peixe
TemplateDoesNotExisterro Estou usando django 1.10.1
Vikrant Singh
1

Não. Em vez disso, use StringTemplate - não há razão para considerar qualquer outro mecanismo de modelo uma vez que você saiba sobre ele.

Rob Williams
fonte
A porta Python se parece muito com Java. Não é python.
Michael Buckley
0

Eu concordo com as afirmações acima. Jinja 2 é um bom superconjunto de templates Django para uso geral. Acho que eles estão trabalhando para tornar os modelos Django um pouco menos acoplados ao settings.py, mas Jinja deve servir bem para você.

Clint Ecker
fonte
0

Durante a execução do manage.pyshell:

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

O Google AppEngineusa o mecanismo de modelagem Django, você já deu uma olhada em como eles fazem isso? Você poderia simplesmente usar isso.

William Keller
fonte