Comme décrit par Nick dans les commentaires de systempuntoout réponse, j'ai inséré cette use_library()
code à partir d'ici dans chaque gestionnaire que les importations de django (soit directement ou par l'intermédiaire de google.appengine.ext.webapp.template
ou même juste django.utils.simplejson
):
from google.appengine.dist import use_library
use_library('django', '1.2')
Comme suggéré par Nick, cela a été rendu plus facile par la première refactoring de réduire le nombre de gestionnaires référencé par l'app.yaml (c'est à dire, plus près du scénario 1 décrit ici).
Cependant, j'ai l'appstats builtin configuré, et si j'ai d'abord allé à l' /_ah/appstats après un téléchargement, alors j'obtiens cette erreur:
<'de google.appengine.dist._library.UnacceptableVersionError'>:
django 1.2 a été demandé, mais
0.96.4.Aucun n'est déjà en cours d'utilisation
J'ai été en mesure de résoudre ce problème en incluant également l' use_library()
code appengine_config.py
.
J'ai remarqué que par l'insertion d'un appel à l' use_library()
en appengine_config.py
, alors qu'il n'était plus nécessaire dans tous mes maîtres. En particulier ceux qui importent google.appengine.ext.webapp.template
n'en ont pas besoin, parce que l'importation webapp.template
charge appengine_config.py
. Le appstats de l'INTERFACE utilisateur importations webapp.template
, c'est pourquoi cette résolu le problème.
Cependant, j'ai eu quelques gestionnaires (par exemple json services) qui ne sont pas importés webapp.template
, mais ne l'importation django.utils.simplejson
. Ces gestionnaires exigent toujours un appel direct à l' use_library()
. Si, au contraire, ces gestionnaires sont appelés d'abord sur une nouvelle instance, l' UnacceptableVersionError
se produit. Bien que je suis en utilisant appengine_config.py
pour configurer appstats, signification, appengine_config.py
est appelé à l'instrument, à toutes les demandes, il est appelé trop tard dans le cycle de vie de page pour configurer correctement la bonne version de Django.
Tout cela est apparu à travailler bien au début, mais ensuite j'ai découvert un en arrière de l'incompatibilité entre le nouveau Django 1.2 et le vieux Django 0.96 qui j'avais été en utilisant. Mon projet de construction est comme ceci:
root
+- admin
| +- page_admin.html
+- page_base.html
Avec Django, 0.96, avoir de la suite dans page_admin.html a bien fonctionné:
{% extends "../page_base.html" %}
Avec Django 1.2, j'ai eu cette erreur:
TemplateDoesNotExist: ../page_base.html
Le changement dans Django 1.2 semble que par défaut, Django ne permet pas le chargement des modèles qui sont au-dessus du modèle d'origine du répertoire.
Une solution de contournement pour ce qui est décrit ici, mais cette approche ne pouvait pas fonctionner pour moi, car il exige que les modèles à être dans un des modèles de sous-répertoire.
La solution c'est d'installer un settings.py
le fichier, définissez l' TEMPLATE_DIRS
paramètre le répertoire racine du projet, et puis changer l' extends
balise juste référence "page_base.html"
, comme décrit ici. Cependant, j'ai rencontré deux problèmes en essayant de le faire.
J'ai été en utilisant le code recommandé de rendre mon modèle, c'est à dire:
template_values = { ... }
path = os.path.join(os.path.dirname(__file__), 'page_admin.html')
self.response.out.write(template.render(path, template_values))
Le premier problème est qu' template.render()
remplace l' TEMPLATE_DIRS
réglage pour le répertoire du modèle en cours de rendu. La solution est donc le code suivant:
template_values = { ... }
path = os.path.join(os.path.dirname(__file__), 'page_admin.html')
template_file = open(path)
compiled_template = template.Template(template_file.read())
template_file.close()
self.response.out.write(compiled_template.render(template.Context(template_values)))
Un inconvénient de cette approche est que, template.render()
caches de la compilation des templates, alors que ce code ne fonctionne pas (bien que ce ne serait pas difficile d'en rajouter).
Pour configurer l' TEMPLATE_DIRS
réglage, j'ai ajouté un settings.py
mon projet:
PROJECT_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (PROJECT_ROOT,)
Et puis dans tous mes maîtres-chiens, avant de l' use_library()
code, j'ai mis l' DJANGO_SETTINGS_MODULE
comme décrit ici:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
Le deuxième problème est que cela n'a pas fonctionné - le fichier de paramètres n'était pas chargé, et donc l' TEMPLATE_DIRS
était vide.
Django paramètres sont chargés de l'spécifiée settings.py
paresseusement, la première fois qu'ils sont accessibles. Le problème, c'est que l'importation d' webapp.template
des appels django.conf.settings.configure()
à essayer de configurer certains paramètres. Par conséquent, si webapp.template
est importé, avant tous les paramètres sont accessibles, alors settings.py
n'est jamais chargé (comme les paramètres de l'accesseur constate qu'il existe déjà des paramètres, et ne pas essayer de charger plus).
La solution à cela est de forcer un accès aux paramètres, à la charge de l' settings.py
, avant d' webapp.template
est importé. Puis, quand webapp.template
est ensuite importé, son appel à l' django.conf.settings.configure()
est ignoré. J'ai donc changé le Django d'installation de version de code dans tous mes maîtres-chiens (et appengine_config.py
) pour les opérations suivantes:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
from django.conf import settings
_ = settings.TEMPLATE_DIRS
Dans la pratique, j'ai effectivement mis tout le code ci-dessus dans un fichier appelé" setup_django_version.py
, puis les importer à partir de l'ensemble de mes gestionnaires, plutôt que de dupliquer ces 6 lignes de code partout.
J'ai ensuite mis à jour mon page_admin.html
template à inclure ce (c'est à dire spécifier page_base.html
par rapport à l' TEMPLATE_DIRS
du réglage):
{% extends "page_base.html" %}
Et qui a résolu le problème avec le rendu de la page d'administration.