【问题标题】:Python Google App Engine. GET Request sent twicePython 谷歌应用引擎。 GET 请求发送两次
【发布时间】: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


【解决方案1】:

您的问题是缺少关键信息,路线是如何设置的,模板代码在哪里?问题显然来自客户端,请求来自哪里?你应该提供这方面的信息。

无论如何,出于某种奇怪的原因,我想我可能知道它是什么......

我猜当你渲染页面时,你有一些带有 url 的 img 标签,并且该 url 是 event.poster_url,如果上传,它将是你从 get_serving_url 得到的任何东西,但如果还没有发生但值将是None

我也猜测当前位置(在浏览器中,当问题发生时)是/events/event_info/,所以在第二种情况下会导致对/events/event_info/None 的请求。

希望我的水晶球能用 :)

【讨论】:

  • 谢谢詹姆。如果有帮助,我已编辑添加模板代码。您说得对,模板代码包含您所指的 img 标签。好水晶球!为什么 GET 请求会被调用两次?
  • 模板代码是指模板本身 (html/jinja2),而不是您如何称呼它。至于你的问题,这就是我在倒数第二句话中写的,如果我的假设是正确的,那么图像请求将再次到达你的服务器。
  • 好的,我明白了。 html/jinja2 与您假设的一样。像这样的图像请求两次访问服务器是否正常?我可以防止这种行为吗?这是必要的,还是只是在 BaseHandler 中检查 None 并做出相应响应的情况?我只是想了解这里的过程。谢谢!
  • 它与图像本身无关,一切正常。如果没有要显示的图像,那么您根本就不应该有 img 标签,因为它会指向什么?突然你引入了未定义的(尽管是正确的)行为!正确的做法是将其包裹在{% if event.poster_url %}<img ...>{% endif %} 中,你就是金子 :)
  • 好的,杰米。我得到了它。 Gracias amigo, eres un crack。规则1:不要惊慌。规则2:这是正常的。我将它包装在 if 子句中,就是这样。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2014-05-25
  • 2017-04-10
  • 2014-03-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
相关资源
最近更新 更多