I am in the process of migrating some GAE apps from Python 2.5 to 2.7. It seems much more difficult to import Django templates (any version) into this version of Python. I followed Google's instructions to the T and scoured the web for help, but ultimately failed. So here is what I tried, and I was wondering if any of you guys would be able to help me! Thanks in advance.
In app.yaml:
libraries:
- name: django
version: "1.2"
In main.yaml:
import os
# specify the name of your settings module
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
app = django.core.handlers.wsgi.WSGIHandler()
The main class:
class Main(webapp2.RequestHandler):
def get(self):
self.response.out.write(template.render('index.html', None))
The Error I get:
NameError: global name 'template' is not defined
Interestingly, it worked with Jinja2 templates. However, all HTML code was written using Django templates and I think it would be too time consuming to convert them all. Here's the Jinja2 code that worked (all in one code block for simplicity).
libraries:
- name: jinja2
version: latest
import jinja2
import os
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class Main(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render())
Your template is undefined; you'll need to import it from webapp:
from google.appengine.ext.webapp import template
webapp2 is backwards compatible with webapp but you'll need to use the template engine from webapp still, see Using templates.
Related
I am trying to deploy my personal website but I am running into a big error when I run my website in local host everything runs fine.But I have deployed my website via Google App but it does not work. I keep getting this error below Here is a screenshot of the error I get
I don't know why it is doing this because that Homepage.html file is inside of the template folder. This a screenshot of my file path and the Python code I wrote.
This the code I wrote
import jinja2
import os
import webapp2
import logging
from google.appengine.api import users
from google.appengine.ext import ndb
import datetime
import json
import unicodedata
from google.appengine.api import users
# the two lines of code below makes the jinja work
jinja_environment = jinja2.Environment(loader=
jinja2.FileSystemLoader(os.path.dirname(__file__)))
class HomePage(webapp2.RequestHandler):
def get(self):
template =
jinja_environment.get_template('templates/HomePage.html')
self.response.write(template.render())
class AboutMe(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('templates/Aboutme.html')
self.response.write(template.render())
class Contact(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('templates/Contact.html')
self.response.write(template.render())
class Projects(webapp2.RequestHandler):
def get(self):
template =
jinja_environment.get_template('templates/Projects.html')
self.response.write(template.render())
app = webapp2.WSGIApplication([
('/', HomePage), #HomePage
('/AboutMe.html',AboutMe),
('/Contact.html',Contact),
('/Projects.html',Projects)
], debug=True)
}
here is my app.yaml file
application: israel-ali
version: 1
runtime: python27
api_version: 1
threadsafe: yes
# order matters always have this order
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: /resources
static_dir: static_folder
- url: .*
script: main.app
libraries:
- name: jinja2
version: latest
- name: webapp2
version: "2.5.2"
[enter image description here][3]
Filenames are case sensitive on GAE.
Your code seeks a template called HomePage.html and (what I suspect to be) the actual template is called Homepage.html. And you have a similar problem with Aboutme.html vs. AboutMe.html.
You just need to use the actual filename in .get_template().
Is the operating system you're using locally one that doesn't treat case in filenames as significant? If so, those template_get lines need to specify filenames exactly as they are on the filesystem.
I am trying to run a django app and a webapp2 app together in one python interpreter. I'm using werkzeug for that as described here.
Here's my sample code.
from werkzeug.wsgi import DispatcherMiddleware
from django_app import application as djangoapp
from webapp2_app import application as webapp2app
application = DispatcherMiddleware(djangoapp, {
'/backend': webapp2app
})
After doing this, I would expect all requests to /backend should be treated by the webapp2 app as /. But it treats the requests as /backend. This work fines with other WSGI apps using django or flask. The problem only appears with webapp2 apps. Does anyone have any suggestions how to overcome this? Is there any other way I can achieve my purpose without using werkzeug for serving multiple WSGI apps under one domain?
DispatcherMiddleware fabricates environments for your apps and especially SCRIPT_NAME. Django can deal with it with configuration varibale FORCE_SCRIPT_NAME = '' (docs).
With Webapp2 it's slightly more complicated. You can create subclass of webapp2.WSGIApplication and override __call__() method and force SCRIPT_NAME to desired value. So in your webapp2_app.py it could be like this
import webapp2
class WSGIApp(webapp2.WSGIApplication):
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return super(WSGIApp, self).__call__(environ, start_response)
# app = WSGIApp(...)
I am trying to set up unit testing of a series of Django templates in Google App Engine using the python unittest framework.
The app uses python 2.7, webapp2, Django 1.2, and is already using unittest for testing the none Django functionality. The Django templates have no issues serving through the server in dev and live environments.
When executing the page call through the unittest framework the following error is raised:
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django_1_2/django/template/loader.py", line 138, in find_template
raise TemplateDoesNotExist(name)
TemplateDoesNotExist: site/index.html
Settings.py:
import os
PROJECT_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, "templates"),
)
Unit test call:
import webapp2
import unittest
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.2')
import main
class test_main(unittest.TestCase):
def test_default_page(self):
request = webapp2.Request.blank('/')
response = request.get_response(main.app)
self.assertEqual(response.status_int, 200)
I've found it necessary to specify DJANGO_SETTINGS_MODULE and the Django version within the test file even though these are normally specified through app.yaml
The page handler:
from django.template.loaders.filesystem import Loader
from django.template.loader import render_to_string
class default(webapp2.RequestHandler):
def get(self):
self.response.out.write(render_to_string('site/index.html'))
I've tried stripping everything out of index.html but still get the same error.
I've tried using an explicit path for TEMPLATE_DIRS but no change.
Any ideas?
Check if this is set anywhere in your django config:
TEMPLATE_LOADERS=('django.template.loaders.filesystem.load_template_source',)
Can anyone suggest a detailed resource for including django 1.2 templating in our GAE apps? So far I have found
docs describing how to zip up the django files and add them to our project
docs on running native django projects in GA
docs about including 1.0 and 1.1 libraries into our projects
but nothing yet describing how to use django 1.2 templates in our projects. Specifically, how to formulate the arcane wizardry at the top of my python script that will magically convince GAE to use my zipped up django library.
I have this in my python script:
import sys
sys.path.insert(0, 'django/django.zip')
And similar to the GAE tutorial, here's how I'm rendering the template:
template_values = {
'formerror': formerror,
'media': media,
'status': status
}
path = os.path.join(os.path.dirname(__file__), formtemplate)
self.response.out.write(template.render(path, template_values)
But there is some piece missing for GAE to use Django 1.2 to render the templates. What is it?
I used this:
from google.appengine.dist import use_library
use_library('django', '1.1')
from google.appengine.ext.webapp import template
In this case I used 1.1 version but I think it should work the same for 1.2.
I had the same problem a while ago - I wanted to use version 1.2 version for templates instead of 0.96 (that is provided by GAE). The following code seems to work for me.
# some standard Google App Engine imports (optional)
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext import db
# Remove Django modules (0.96) from namespace
for k in [k for k in sys.modules if k.startswith('django')]:
del sys.modules[k]
# Force sys.path to have our own directory first, in case we want to import
# from it. This way, when we import Django, the interpreter will first search
# for it in our directory.
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__)))
# Must set this env var *before* importing any part of Django
# (that's required in Django documentation)
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
# New Django imports
from django.template.loader import render_to_string
from django.conf import settings
# Configure dir with templates
# our template dir is: /templates
TEMPLATE_DIR = os.path.join(os.path.dirname(__file__),'templates')
settings.configure(TEMPLATE_DIRS = (TEMPLATE_DIR,'') )
However, if you need only templates from Django, and no other API, consider using Jinja instead. That's what I'm planning to do.
I'm a Python newbie, so I'm sure this is easy. Here's the code in my main.py:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.1')
# Use django form library.
from django import forms
from django.shortcuts import render_to_response
The last line breaks with an ImportError. If I don't include that, then I get an error that "render_to_response" isn't available. What am I doing wrong?
Well, render_to_response is a shortcut for this, so give this a try:
from django.template import Context, loader
from django.http import HttpResponse
def render_to_response(tmpl, data):
t = loader.get_template(tmpl)
c = Context(data)
return HttpResponse(t.render(c))
render_to_response("templates/index.html", {"foo": "bar"})
In this case the problem ended up being that Google App Engine uses version 0.96 of Django and it actually couldn't find the 'redirect' method, because that's only in Django 1.1. If you use the GAE utility method 'use_library' you can specify what version of the Django framework you want to use and this problem goes away.