【发布时间】:2015-05-17 15:31:11
【问题描述】:
当用户单击 Google App Engine、Python 应用程序中的链接时,将发送两次 GET 请求。该App使用webapp2和jinja2。
仅当数据存储模型“事件”中缺少 Blobstore 映像时才会发生这种情况。 如果图像出现在“事件”中,则日志中仅记录一个 GET 请求。 如果用户尚未上传 blobstore 图像,则有第二个 GET 请求,该请求返回 NoneType 错误。
GET 请求发送到同一个处理程序“InfoHandler(BaseHandler)”。
代码:
NDB 模型:
class Event(ndb.Model):
"""datastore class for storing events"""
# : event properties
org_user = ndb.StringProperty() #ID string for the Organiser
poster_url = ndb.StringProperty() #blobstore image url
poster_key = ndb.StringProperty() #blobstore image key
....
基本处理程序:
def get_obj_from_url(self, position, kind):
""" returns a datastore object from a url"""
#: first get the url string
url_string = self.request.url
#: then split the string on POSITION to get the key value
key_value = url_string.split('/')[position]
#: now query to get the entity instance from the key value
qry = ndb.Key(kind, key_value)
#: finally you can get the datastore object
db_obj = qry.get()
return db_obj
用于渲染页面的events.py
class InfoHandler(BaseHandler):
"""handler to render the event info page"""
def get(self):
#: SET LOCALE
self.set_locale()
#: TEST FOR THE USER
user_id = self.user_obj()
if user_id:
if db_user.User.get_by_id(user_id):
#: get the user info from datastore
info = db_user.User.get_by_id(user_id)
#: get the event object from the datastore
event_obj = self.get_obj_from_url(-1, "Event")
org_user_id = event_obj.org_user
记录错误堆栈:
- [14/Mar/2015:07:20:13 -0700] "GET /events/event_info/None HTTP/1.1" 500 719 "http://www.x.com/events/event_info/example_event" "Mozilla/5.0 (Linux; Android 4.4.2; SM-T805 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.109 Safari/537.36" "www.x.com" ms=94 cpu_ms=76 cpm_usd=0.000080 app_engine_release=1.9.18 instance=00c61b117c03db016d0f4da5a9f36a8e9aea83fd
E 2015-03-14 15:20:13.235
'NoneType' object has no attribute 'org_user'
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/ webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/ webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/ webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/ webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/ webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/ webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/s~x/0-9-9-9- 4.382865846043625422/events/events.py", line 753, in get
org_user_id = event_obj.org_user
AttributeError: 'NoneType' object has no attribute 'org_user'
此错误不会影响用户,因为第一个 GET 请求返回“事件”对象,没有图像,并且页面呈现时没有错误。 然而,这是我想弄清楚的一个怪癖。
为什么 GET 请求被发送两次?
感谢您的帮助。
编辑:
模板代码:
def render_template(self, route, filename, template_values):
""" you need a function to render the template from jinja.
takes these inputs:
route - route to template folder
filename - the name of the template
template_values - the values returned in the template
"""
#: first you need to define the loader environment and extensions
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(route),
autoescape=True,
extensions=['jinja2.ext.i18n'])
#: you need to set gettext to retrieve translation from templates via the {{trans}} tag
jinja_env.install_gettext_translations(i18n)
#: you need to set the attribute, template, using the filename value
template = jinja_env.get_template(filename)
#: now you can output the template with the template_values
self.response.write(template.render(template_values))
【问题讨论】:
-
那么问题是什么?!
-
为什么GET请求被发送了两次。
-
您确定该职位是
-1而不是1?因为在我看来,至少您的错误消息是因为get_obj_from_url返回None -
在我看来,您应该在尝试对其采取行动之前检查有效的 event_obj。也许记录一个警告,以便您可以追踪人们访问不存在的事件的原因
-
绝对是-1。链接是:/events/event_info/event_key。这总是在第一个 GET 请求中正确返回。如果 blobstore 图像丢失,则第二个 GET 请求返回 NoneType,并且根据 Stack Trace 链接中的 None。
标签: python google-app-engine jinja2 blobstore webapp2