Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何制作';permalink';在Google App Engine webapp2留言簿教程中显示两幅图像的详细信息页面_Python_Google App Engine_Google Cloud Datastore_Webapp2_Blobstore - Fatal编程技术网

Python 如何制作';permalink';在Google App Engine webapp2留言簿教程中显示两幅图像的详细信息页面

Python 如何制作';permalink';在Google App Engine webapp2留言簿教程中显示两幅图像的详细信息页面,python,google-app-engine,google-cloud-datastore,webapp2,blobstore,Python,Google App Engine,Google Cloud Datastore,Webapp2,Blobstore,我正在关注(这是他们的)并希望: 允许留言簿用户在发布问候语时除了“化身”之外,还可以上传额外的图像。这可以称为“其他” 发布问候语后,将用户重定向到带有类似/greeting/numeric id的URL的问候语详细页面,而不是列出所有问候语的主页 使用名为detail.html的Jinja2模板显示带有图像的详细信息页面 我无法理解: A)如何编写在发布问候语后调用的重定向代码,使其重定向到类似于/greeting/numeric id的URL B)如何编写用户重定向到的详细视图和模板页面,

我正在关注(这是他们的)并希望:

  • 允许留言簿用户在发布问候语时除了“化身”之外,还可以上传额外的图像。这可以称为“其他”
  • 发布问候语后,将用户重定向到带有类似/greeting/numeric id的URL的问候语详细页面,而不是列出所有问候语的主页
  • 使用名为detail.html的Jinja2模板显示带有图像的详细信息页面
  • 我无法理解:

    A)如何编写在发布问候语后调用的重定向代码,使其重定向到类似于/greeting/numeric id的URL

    B)如何编写用户重定向到的详细视图和模板页面,以便显示问候id图像

    下面的图表显示了我要做的事情:

    这是留言簿.py

    import os
    import urllib
    from google.appengine.api import images
    from google.appengine.api import users
    from google.appengine.ext import ndb
    from google.appengine.ext.webapp import blobstore_handlers
    from google.appengine.ext import blobstore
    import jinja2
    import webapp2
    
    JINJA_ENVIRONMENT = jinja2.Environment(
        loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
        extensions=['jinja2.ext.autoescape'],
        autoescape=True)
    
    DEFAULT_GUESTBOOK_NAME = 'default_guestbook'
    
    def guestbook_key(guestbook_name=None):
        """Constructs a Datastore key for a Guestbook entity with name."""
        return ndb.Key('Guestbook', guestbook_name or 'default_guestbook')
    
    class Author(ndb.Model):
        """Sub model for representing an author."""
        identity = ndb.StringProperty(indexed=False)
        email = ndb.StringProperty(indexed=False)
    
    class Greeting(ndb.Model):
        """A model for representing an individual Greeting entry."""
        author = ndb.StructuredProperty(Author)
        date = ndb.DateTimeProperty(auto_now_add=True)
        avatar = ndb.BlobProperty(indexed=False, required=True)
        other = ndb.BlobProperty(indexed=False, required=True)
    
    class MainPage(webapp2.RequestHandler):
        def get(self):
            self.response.out.write('<html><body>')
            guestbook_name = self.request.get('guestbook_name')
    
            greetings = Greeting.query(
                ancestor=guestbook_key(guestbook_name)) \
                .order(-Greeting.date) \
                .fetch(10)
    
            self.response.out.write("""
                  <form action="/sign?%s"
                        enctype="multipart/form-data"
                        method="post">
                    <label>Avatar:</label>
                    <input type="file" name="avatar"/><br>
                    <label>Other Image:</label>
                    <input type="file" name="other"/><br>
                    <input type="submit" value="Submit">
                  </form>
                </body>
              </html>""" % (urllib.urlencode({'guestbook_name': guestbook_name})))
    
    class Image(webapp2.RequestHandler):
        """ Handle image stored as blobs of bytes. 
            No idea how the template knows to select a particular one. """
        def get(self):
            avatar_greeting_key = ndb.Key(urlsafe=self.request.get('avatar_id'))
            other_greeting_key = ndb.Key(urlsafe=self.request.get('other_id'))
            avatar_greeting = avatar_greeting_key.get()
            other_greeting = other_greeting_key.get()
            if avatar_greeting.avatar:
                self.response.headers['Content-Type'] = 'image/png'
                self.response.out.write(avatar_greeting.avatar)
            elif other_greeting.other:
                self.response.headers['Content-Type'] = 'image/png'
                self.response.out.write(other_greeting.other)
            else:
                self.response.out.write('No image')
    
    class Guestbook(webapp2.RequestHandler):
        def post(self):
            guestbook_name = self.request.get('guestbook_name',
                                              DEFAULT_GUESTBOOK_NAME)
            greeting = Greeting(parent=guestbook_key(guestbook_name))
    
            if users.get_current_user():
                greeting.author = Author(
                        identity=users.get_current_user().user_id(),
                        email=users.get_current_user().email())
    
            avatar = self.request.get('avatar')
            avatar = images.resize(avatar, 100, 100)  
            other = self.request.get('other')
            other = images.resize(other, 400, 300)  
    
            greeting.avatar = avatar
            greeting.other = other
    
            greeting.put()
    
            query_params = {'guestbook_name': guestbook_name}
            self.redirect('/greeting/%d' % greeting.key.id())
    
    class Detail(webapp2.RequestHandler):
        """ Individual greeting. """
        def get(self, *args, **kwargs):
            guestbook_name = self.request.get('guestbook_name', DEFAULT_GUESTBOOK_NAME)
    
            greeting = Greeting.get_by_id(args[0],
                                              parent=guestbook_key(guestbook_name))
    
            template_values = {
                'greeting': greeting,
            }
    
            template = JINJA_ENVIRONMENT.get_template('detail.html')
            self.response.write(template.render(template_values))
    
    
    app = webapp2.WSGIApplication([
        ('/', MainPage),
        ('/img', Image),
        ('/sign', Guestbook),
        ('/greeting/(\d+)', Detail),
        ], debug=True)
    
    错误:

    Traceback (most recent call last):
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
        rv = self.handle_exception(request, response, e)
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
        rv = self.router.dispatch(request, response)
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
        return route.handler_adapter(request, response)
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
        return handler.dispatch()
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
        return self.handle_exception(e, self.app.debug)
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
        return method(*args, **kwargs)
      File "/Users/simon/Projects/guestbook/guestbook.py", line 111, in get
        self.response.write(template.render(template_values))
      File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 894, in render
        return self.environment.handle_exception(exc_info, True)
      File "/Users/simon/Projects/guestbook/detail.html", line 9, in top-level template code
        Avatar: <img src="/img?avatar_id={{ greeting.key.urlsafe() }}">
    UndefinedError: 'None' has no attribute 'key'
    
    回溯(最近一次呼叫最后一次):
    文件“/Users/simon/Projects/google cloud sdk/platform/google\u appengine/lib/webapp2-2.5.2/webapp2.py”,第1535行,在__
    rv=自身处理异常(请求、响应、e)
    文件“/Users/simon/Projects/google cloud sdk/platform/google\u appengine/lib/webapp2-2.5.2/webapp2.py”,第1529行,在__
    rv=自我路由器调度(请求、响应)
    默认情况下,文件“/Users/simon/Projects/google cloud sdk/platform/google\u appengine/lib/webapp2-2.5.2/webapp2.py”第1278行
    返回路由处理程序适配器(请求、响应)
    文件“/Users/simon/Projects/google cloud sdk/platform/google\u appengine/lib/webapp2-2.5.2/webapp2.py”,第1102行,在__
    返回处理程序.dispatch()
    文件“/Users/simon/Projects/google cloud sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py”,第572行,在调度中
    返回self.handle_异常(e,self.app.debug)
    文件“/Users/simon/Projects/google cloud sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py”,第570行,在调度中
    返回方法(*args,**kwargs)
    get中第111行的文件“/Users/simon/Projects/guestbook/guestbook.py”
    self.response.write(template.render(template_值))
    文件“/Users/simon/Projects/google cloud sdk/platform/google_appengine/lib/jinja2-2.6/jinja2/environment.py”,第894行,在render中
    返回self.environment.handle\u异常(exc\u info,True)
    顶级模板代码中的第9行文件“/Users/simon/Projects/guestbook/detail.html”
    化身:
    UndefinedError:“None”没有属性“key”
    
    任何帮助,或者更好的示例代码,都将不胜感激。 一个GAE/webapp2博客教程,其中包含详细代码示例、列表视图和模板,这将非常好,但也许GAE BlobStore的数据结构并不适合博客

    更新:
    如果我在Dan的回答中添加python检查代码,我会得到一个500错误而不是堆栈跟踪,如果我尝试模板检查,我会得到一个空白的问候页面。我已经用我的完整代码和一个图表更新了这个问题,解释了我要做的事情。

    我将从
    B
    开始:

    错误表明
    问候语
    值为
    ,导致在模板呈现期间,当jinja2尝试在
    {{greeting.key.urlsafe()}
    中展开
    问候语.key
    时出现异常

    一个选项是重新安排处理程序代码,以防止在不满足必要条件时呈现该模板,可能是以下内容:

        ...
        greeting = Greeting.get_by_id(args[0])
    
        if not greeting or not isinstance(greeting.key, ndb.Key):
            # can't render that template, invalid greeting.key.urlsafe()
            webapp2.abort(500)  
            return
    
        template_values = {
            'greeting': greeting,
        }
    
        template = JINJA_ENVIRONMENT.get_template('detail.html')
        self.response.write(template.render(template_values))
        ...
    
    {% if greeting and greeting.key %}<img src="/img?avatar_img_id={{ greeting.key.urlsafe() }}">{% endif %}
    
    /guestbook/<guestbook_name>/greeting/<numeric-id>.
    
    或者,您可以使用适当的检查来包装引用变量的模板区域(IMHO更丑陋、更硬、更脆弱,tho-python比jinja2更适合这种逻辑),大致如下:

        ...
        greeting = Greeting.get_by_id(args[0])
    
        if not greeting or not isinstance(greeting.key, ndb.Key):
            # can't render that template, invalid greeting.key.urlsafe()
            webapp2.abort(500)  
            return
    
        template_values = {
            'greeting': greeting,
        }
    
        template = JINJA_ENVIRONMENT.get_template('detail.html')
        self.response.write(template.render(template_values))
        ...
    
    {% if greeting and greeting.key %}<img src="/img?avatar_img_id={{ greeting.key.urlsafe() }}">{% endif %}
    
    /guestbook/<guestbook_name>/greeting/<numeric-id>.
    
    你需要打电话:

        greeting = Greeting.get_by_id(args[0],
                                      parent=guestbook_key(guestbook_name))
    
    如果您想继续朝同一方向前进,还可以在问候语URL中对
    留言簿名称
    进行编码,这将允许您也获得所需的父密钥,可能是以下内容:

        ...
        greeting = Greeting.get_by_id(args[0])
    
        if not greeting or not isinstance(greeting.key, ndb.Key):
            # can't render that template, invalid greeting.key.urlsafe()
            webapp2.abort(500)  
            return
    
        template_values = {
            'greeting': greeting,
        }
    
        template = JINJA_ENVIRONMENT.get_template('detail.html')
        self.response.write(template.render(template_values))
        ...
    
    {% if greeting and greeting.key %}<img src="/img?avatar_img_id={{ greeting.key.urlsafe() }}">{% endif %}
    
    /guestbook/<guestbook_name>/greeting/<numeric-id>.
    
    /guestbook//greeting/。
    
    您还需要仔细查看图像处理。架构不一致:在图表和模型中,化身和另一个图像都附加到单个问候语实体,但在
    图像处理程序中,它们中的每一个都附加到单独的问候语。处理程序也根本不映射到图像的URL(这还需要对定位适当图像所需的数据进行额外编码,具体取决于体系结构决策)


    恐怕你还有很多工作要做,直到你把整个事情都做好,远远超过一个简单的问题。退一步,重新思考您的架构,将其分成更小的部分,一次只关注一个部分,然后继续。在您熟悉了各种部件的技术之后,您会觉得立即解决整个问题更好。

    问题出在哪里?你有什么错误吗?代码不起作用?我在顶级模板代码UndefinedError中添加了错误-
    文件“/Users/simon/Projects/guestbook/detail.html”,第11行:“None”没有属性“key”
    非常感谢,Dan。我会在有时间的时候尝试,如果我能让它工作,我会接受这个答案。如果我添加python检查代码,我会得到一个500错误而不是堆栈跟踪,如果我尝试模板检查,我会得到一个空白的问候页面。我已经用我的完整代码和一个图表更新了这个问题,解释了我要做的事情。你能提供一个在问候语“permalink”URL中编码留言簿名称的示例吗?我接受这个答案,因为它帮助我朝着正确的方向前进,即使我还不能让事情顺利进行。