Comment utiliser les modèles Django sans le reste de Django?

101

Je souhaite utiliser le moteur de modèle Django dans mon code (Python), mais je ne construis pas de site Web basé sur Django. Comment l'utiliser sans avoir de fichier settings.py (et autres) et avoir à définir la variable d'environnement DJANGO_SETTINGS_MODULE?

Si j'exécute le code suivant:

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

Je reçois:

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

Réponses:

133

La solution est simple. C'est en fait bien documenté , mais pas trop facile à trouver. (J'ai dû creuser - cela ne s'est pas produit lorsque j'ai essayé plusieurs recherches Google différentes.)

Le code suivant fonctionne:

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

Consultez la documentation de Django (lien ci-dessus) pour une description de certains des paramètres que vous voudrez peut-être définir (comme arguments de mots clés à configurer).

Daryl Spitzer
la source
13
Et pour l'obtenir à partir d'un fichier: settings.configure (TEMPLATE_DIRS = (".",)) T = get_template ('test.html')
Bryce
La documentation pour settings.configure () est ici - docs.djangoproject.com/en/1.7/topics/settings
Scott
À partir du lien "bien documenté" ci-dessus, cela est vrai jusqu'à la version 1.7. À partir de la version 1.8, il semble que vous n'en ayez plus besoin settings.configure().
Olaf Dietsche
Si vous souhaitez inclure d'autres modèles ou utiliser l'héritage de modèles, la solution ci-dessus de Bryce est nécessaire.
titusjan
6
J'avais également besoin d'appeler django.setup () avant le constructeur de Template.
Amit le
44

La syntaxe Jinja2 est à peu près la même que celle de Django avec très peu de différences, et vous obtenez un moteur de template beaucoup plus puissant, qui compile également votre template en bytecode (FAST!).

Je l'utilise pour créer des modèles, y compris dans Django lui-même, et c'est très bien. Vous pouvez également écrire facilement des extensions si une fonctionnalité souhaitée manque.

Voici une démonstration de la génération de code:

>>> 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
la source
4
J'utilise Jinja dans un de mes projets, parce que je voulais quelque chose que je connaissais assez bien, mais je ne voulais pas que mes utilisateurs (puisqu'il s'agit d'une application distribuable) aient à installer Django. Un avantage est que Jinja peut être installé avec easy_install.
Xiong Chiamiov
4
Django peut également être installé avec easy_install.
hegemon
Jinga ne prend pas encore officiellement en charge Python3. Selon le site, c'est encore expérimental.
Pramod
9

Une raison particulière pour laquelle vous souhaitez utiliser les modèles de Django? Les deux Jinja et Genshi sont, à mon avis, supérieur.


Si vous le souhaitez vraiment, consultez la documentation Django sursettings.py . Surtout la section "Utilisation des réglages sans réglage DJANGO_SETTINGS_MODULE". Utilisez quelque chose comme ceci:

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

Je recommanderais également jinja2. Il y a un bel article sur djangovs jinja2qui donne des informations détaillées sur les raisons pour lesquelles vous devriez préférer le plus tard.

olt
la source
Je préfère Jinja2 en raison de sa {% set %}syntaxe et de son égalité avec le moteur de template Twig (PHP). Il est préférable d'écrire toujours du code multiplateforme, mais la différence de performance n'est pas critique - par exemple, python fonctionnera toujours plus lentement que PHP, donc si vous avez besoin de performances, vous feriez mieux de créer un site avec PHP, Twig et Symfony2 ou autre. Triste mais vrai.
Croll
@Croll, Si votre site Web effectue des calculs complexes, les bibliothèques Python sont incomparablement plus rapides, sinon le goulot d'étranglement est la base de données ou vous faites probablement quelque chose de vraiment mal
Bob
4

Selon la documentation Jinja, le support de Python 3 est encore expérimental . Donc, si vous êtes sur Python 3 et que les performances ne sont pas un problème, vous pouvez utiliser le moteur de template intégré de django.

Django 1.8 a introduit la prise en charge de plusieurs moteurs de modèles, ce qui nécessite une modification de la façon dont les modèles sont initialisés. Vous devez explicitement configurer settings.DEBUGce qui est utilisé par le moteur de template par défaut fourni par django. Voici le code pour utiliser des modèles sans utiliser le reste 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
la source
4

Un ajout à ce que d'autres ont écrit, si vous voulez utiliser Django Template sur Django> 1.7, vous devez donner à votre settings.configure (...) appeler la variable TEMPLATES et appeler django.setup () comme ceci:

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

Ensuite, vous pouvez charger votre modèle comme d'habitude, à partir d'une chaîne:

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

Et si vous avez écrit la variable DIRS dans le .configure, à partir du disque:

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

Erreur Django: aucun backend DjangoTemplates n'est configuré

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

Robert Vanden Eynde
la source
2

Je dirais aussi Jinja . Il est certainement plus puissant que Django Templating Engine et il est autonome .

S'il s'agissait d'un plug externe à une application Django existante, vous pouvez créer une commande personnalisée et utiliser le moteur de création de modèles dans votre environnement de projets. Comme ça;

manage.py generatereports --format=html

Mais je ne pense pas que cela vaille la peine d'utiliser le Django Templating Engine au lieu de Jinja.

muhuk
la source
2

Merci pour l'aide. Voici un autre ajout. Le cas où vous devez utiliser des balises de modèle personnalisées.

Disons que vous avez cette balise de modèle importante dans le module read.py

from django import template

register = template.Library()

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

Voici le fichier de modèle html "temp.html":

{{var|bracewrap}}

Enfin, voici un script Python qui se liera à tous ensemble

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 sortie serait

{stackoverflow.com rox}
Gourneau
la source
django.template.base.add_to_builtins("read")soulève un ValueErrorpour moi.
oarfish
donne une TemplateDoesNotExisterreur J'utilise django 1.10.1
Vikrant Singh
1

Ne fais pas ça. Utilisez plutôt StringTemplate - il n'y a aucune raison d'envisager un autre moteur de modèle une fois que vous en avez connaissance.

Rob Williams
la source
Le port Python ressemble trop à Java. Ce n'est pas pythonique.
Michael Buckley
0

Je fais écho aux déclarations ci-dessus. Jinja 2 est un très bon sur-ensemble de modèles Django à usage général. Je pense qu'ils travaillent à rendre les modèles Django un peu moins couplés à settings.py, mais Jinja devrait bien faire pour vous.

Clint Ecker
la source
0

Lors de l'exécution du manage.pyshell:

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

Google AppEngineutilise le moteur de création de modèles Django, avez-vous examiné comment ils le font? Vous pourriez peut-être simplement l'utiliser.

William Keller
la source