I'm using the webapp framework from google for this. I'm using template.render() in a get method to render a template for me.
I'm using the following code to do this for me
path = os.path.join(os.path.dirname(__file__), file_name)
self.response.out.write(template.render(path, template_values))
Where file_name is the template to render and template_values is a dict() containing any values to be rendered. What if I don't have any values that I want rendered. Do I just pass in an empty dict() object? It doesn't seem like a great solution to me. Should I be using template.load() instead?
(I can't find the docs for the template class over on google app engine either, hence I'm asking.)
You can pass an empty dictionary to it and it doesn't mind. You just have to send it something. Your templates just won't display anything.
template_values = {}
path = os.path.join(os.path.dirname(__file__), file_name)
self.response.out.write(template.render(path, template_values))
Okay, thanks for all the answers.
What I've done is:
def render_template(template_name, template_values=dict()):
path = os.path.join(os.path.dirname(__file__), template_name)
self.response.out.write(template.render(path, template_values))
Which seems to be the most pythonic solution I could come up with.
Since you are rendering a Django template, you need to use render, and you probably can't provide an empty dictionary, as it will complain about not being able to find the variables it expects, unless you enclose each variable reference in an {% if %} block. You should provide a dictionary with all of the keys that the template expects but with empty strings as values.
If you have no template variables to pass in, just pass an empty dictionary. If you do use any variables in the template, they will all evaluate as None.
To make this easier, you could modify your helper code:
def render_template(template_name, template_values = None):
if template_values is None:
template_values = {}
path = os.path.join(os.path.dirname(__file__), template_name)
self.response.out.write(template.render(path, template_values))
Related
Is it possible to have a wagtail RouteablePageMixin route that is a subpath of another?
This is my code:
class MyPage(RoutablePageMixin, Page):
#route("foo/")
def foo(self, request):
view = views.FooView.as_view()
return view(request, self)
#route("foo/bar/")
def bar(self, request):
view = views.BarView.as_view()
return view(request, self)
What happens:
When I visit <page url>/foo/bar/ I get a FooView response, when what I want is a BarView response.
Is this possible to achieve?
Thanks for your help.
Routes are specified as regular expressions, so you need to mark the start and end with ^ and $ to ensure the URL pattern is matched against the whole path, rather than matching on any path that happens to contain the given pattern as a substring.
#route("^foo/$")
#route("^foo/bar/$")
Alternatively, you could make use of the fact that the patterns are checked in the order they appear in the code, and put the more specific one first:
class MyPage(RoutablePageMixin, Page):
#route("foo/bar/")
def bar(self, request):
view = views.BarView.as_view()
return view(request, self)
#route("foo/")
def foo(self, request):
view = views.FooView.as_view()
return view(request, self)
I use parent_page_types and subpage_types happily all around my Page-models.
But I'm stuck at allowing my class HomePage(Page) only as a direct child at root level.
Any hints?
Try this:
parent_page_types = ['wagtailcore.Page']
also, for completeness, to allow only one instance of a Homepage, add this classmethod to your HomePage:
#classmethod
def can_create_at(cls, parent):
# You can only create one of these!
return super(HomePage, cls).can_create_at(parent) \
and not cls.objects.exists()
First of all, thumbs up for #Serafeim answer, but I will post my answer for people searching for issue similar to mine.
I wanted to achieve the same thing but for a specifi parent in multi-site mode. Meaning I wanted to have multiple site "HomePage" but each "HomePage" can only include one "SearchIndexPage". So the above answer would be modified to
#classmethod
def can_create_at(cls, parent):
# You can only create one of these!
return super(SearchIndexPage, cls).can_create_at(parent) \
and parent.get_children().type(SearchIndexPage).count() == 0
I have a google-cloud-endpoints, in the docs, I did'nt find how to write a PATCH method.
My request:
curl -XPATCH localhost:8080/_ah/api/hellogreeting/1 -d '{"message": "Hi"}'
My method handler looks like this:
from models import Greeting
from messages import GreetingMessage
#endpoints.method(ID_RESOURCE, Greeting,`
path='hellogreeting/{id}', http_method='PATCH',
name='greetings.patch')
def greetings_patch(self, request):
request.message, request.username
greeting = Greeting.get_by_id(request.id)
greeting.message = request.message # It's ok, cuz message exists in request
greeting.username = request.username # request.username is None. Writing the IF conditions in each string(checking on empty), I think it not beatifully.
greeting.put()
return GreetingMessage(message=greeting.message, username=greeting.username)
So, now in Greeting.username field will be None. And it's wrong.
Writing the IF conditions in each string(checking on empty), I think it not beatifully.
So, what is the best way for model updating partially?
I do not think there is one in Cloud Endpoints, but you can code yours easily like the example below.
You will need to decide how you want your patch to behave, in particular when it comes to attributes that are objects : should you also apply the patch on the object attribute (in which case use recursion) or should you just replace the original object attribute with the new one like in my example.
def apply_patch(origin, patch):
for name in dir( patch ):
if not name.startswith( '__' ):
setattr(origin,name,getattr(patch,name))
I am trying to make general purpose image display class which
receives two parameters,
Key, and "Column location info in entity"
from URL and return and display specified image delivered from blob.
If you know what I am doing wrong, please give me a hint.
I have datastore "item" like below,
Key | image_index | image1 | image2 | image3 |
and I am requesting image with the URL like below,
http://stackoverwlow.com/image/{key}/{image_N}
I made url handler in the main like below,
def main():
application = webapp.WSGIApplication(
[('/', MainPage),
('/image/([^/]+)/([^/]+)', imageDisplay),
], debug=True)
wsgiref.handlers.CGIHandler().run(application)
and
I made imageDisplay class like below,
from google.appengine.ext import db
from google.appengine.ext import webapp
class imageDisplay(webapp.RequestHandler):
def get(self, _key, _size):
image = db.get(_key)
self.response.headers['Content-Type'] = 'image/jpg'
self.response.out.write(image._size)
But, if I try this code, it will return following error,
global name 'image_size' is not defined
If I specify which image in the entity should be displayed, it works.
So, the data is there.
self.response.out.write(image.image3)
My question is, how to specify "_size" from obtained entity "image"?
Thank you in advance.
With best regards
You need to fetch the attribute programmatically, like this:
self.response.out.write(getattr(image, size))
Since you're addressing your values like an array, you should probably just use one, though: use a db.ListProperty(db.Blob), instead!
I want to be able to take a dynamically created string, say "Pigeon" and determine at runtime whether Google App Engine has a Model class defined in this project named "Pigeon". If "Pigeon" is the name of a existant model class, I would like to then get a reference to the Pigeon class so defined.
Also, I don't want to use eval at all, since the dynamic string "Pigeon" in this case, comes from outside.
You could try, although probably very, very bad practice:
def get_class_instance(nm) :
try :
return eval(nm+'()')
except :
return None
Also, to make that safer, you could give eval a locals hash: eval(nm+'()', {'Pigeon':pigeon})
I'm not sure if that would work, and it definitely has an issue: if there is a function called the value of nm, it would return that:
def Pigeon() :
return "Pigeon"
print(get_class_instance('Pigeon')) # >> 'Pigeon'
EDIT: Another way of doing it is possibly (untested), if you know the module:
(Sorry, I keep forgetting it's not obj.hasattr, its hasattr(obj)!)
import models as m
def get_class_instance(nm) :
if hasattr(m, nm) :
return getattr(m, nm)()
else : return None
EDIT 2: Yes, it does work! Woo!
Actually, looking through the source code and interweb, I found a undocumented method that seems to fit the bill.
from google.appengine.ext import db
key = "ModelObject" #This is a dynamically generated string
klass = db.class_for_kind(key)
This method will throw a descriptive exception if the class does not exist, so you should probably catch it if the key string comes from the outside.
There's two fairly easy ways to do this without relying on internal details:
Use the google.appengine.api.datastore API, like so:
from google.appengine.api import datastore
q = datastore.Query('EntityType')
if q.get(1):
print "EntityType exists!"
The other option is to use the db.Expando class:
def GetEntityClass(entity_type):
class Entity(db.Expando):
#classmethod
def kind(cls):
return entity_type
return Entity
cls = GetEntityClass('EntityType')
if cls.all().get():
print "EntityType exists!"
The latter has the advantage that you can use GetEntityClass to generate an Expando class for any entity type, and interact with it the same way you would a normal class.