python - 如何通过 python 中的 webapp2 处理程序修改 ndb 模型的属性

标签 python google-app-engine google-cloud-datastore app-engine-ndb

我有一个 python 文件和一个 html 文件,它们通过 jinja2 环境以类似于 this tutorial 中的方式相互交互。 .

以下代码控制html文件和python文件之间的交互:

 class MainPage(webapp2.RequestHandler):
     def get(self):
        submission_query = Submission.query().order(-Submission.score)
        submissions = submission_query.fetch(10)

        template_values = {
            'Submission' : Submission,
            'submissions' : submissions,
        }

        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(template_values))

app = webapp2.WSGIApplication([
    ('/', MainPage),
    ('/create', CreateSubmmission),
    ('/voteup', VoteUp),
], debug=True)

我有一个ndb模型如下:

class Submission(ndb.Model):
    username = ndb.StringProperty()
    placename = ndb.StringProperty()
    link = ndb.StringProperty()
    score = ndb.IntegerProperty()

我有一个 html 表单来创建新的提交,如下所示:

<form action="/create" method="post">
    add a new location: <br>
    your name:<div><textarea name="username" rows="2" cols="60"></textarea></div>
    placename:<div><textarea name="placename" rows="2" cols="60"></textarea></div>
    url:<div><textarea name="link" rows="2" cols="60"></textarea></div>
    <div><input type="submit" value="Post"></div>
</form>

使用此请求处理程序:

class CreateSubmmission(webapp2.RequestHandler):
    def post(self):
        submission = Submission()
        submission.username = self.request.get('username')
        submission.placename = self.request.get('placename')
        submission.link = self.request.get('link')
        submission.score = 0
        submission.put()
        self.redirect('/')

我的 html 中有一个部分,它打印出每个提交内容以及一个用于投票的按钮:

{% for Submission in submissions %}
    <p>
        {{Submission.username}} posted:
        <strong><a href="{{Submission.link}}">{{Submission.placename}}</a></strong> <br>
        score:{{Submission.score}}<br>  
        <!--Vote up button-->
        <form action="/voteup?submission={{Submission}}" method="post">
            <div><input type="submit" value="voteup"></div>
        </form>
    </p><br><br>
{% endfor %}

投票由以下 python 类处理:

class VoteUp(webapp2.RequestHandler):
    def post(self):
        submission = self.request.get('Submission')
        submission_key = submission.put()
        the_submission = submission_key.get()
        the_submission.score +=1
        the_submission.put()
        self.redirect('/')

按下按钮时,相应提交的分数属性值应增加 1。

代码在网站sunlit-hook-91816.appspot.com上实现。从该网站上可以看出,按下“赞成”按钮会生成以下错误:

File "/base/data/home/apps/s~sunlit-hook-91816/1.383863233180213164/guestbook.py", line 52, in post
    submission_key = submission.put()
AttributeError: 'str' object has no attribute 'put'

VoteUp 类似乎无法修改 Submission.score 的值。

我正在使用找到的信息here但我不知道如何正确应用它这个问题。谁能告诉我一种让 VoteUp 类修改 Submission.score 的方法?

最佳答案

您正在使用提交对象,就像它可以在 html/python 代码之间传递一样,但它不能,您必须在表单中添加引用并在服务器中取消引用它。

在投票表中执行此操作:

<form action="/voteup?submission={{Submission.key.urlsafe()}}" method="post">
    <div><input type="submit" value="voteup"></div>
</form>

我们在 format safe for http transport 中获取提交的 key ,因此它可以原封不动地返回到服务器。

现在在处理投票时,我们可以重新创建 key 并获取正确的对象:

class VoteUp(webapp2.RequestHandler):
    def post(self):
        submission = self.request.get('submission')
        submission_key = ndb.Key(urlsafe=submission)
        the_submission = submission_key.get()
        the_submission.score +=1
        the_submission.put()
        self.redirect('/')

如您所见,我们只是根据表单中打印的格式化字符串重新创建 key 。

另一种让它变得更好的方法是在表单中使用额外的输入:

<form action="/voteup" method="post">
    <input name="submission" type="hidden" value="{{Submission.key.urlsafe()}}">
    <div><input type="submit" value="voteup"></div>
</form>

您的代码将以相同的方式工作,但我发现它更易于阅读和维护。

关于python - 如何通过 python 中的 webapp2 处理程序修改 ndb 模型的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29871759/

相关文章:

python - 使用其他列的所有数据绘制列中出现次数最多的 (n) 个值

python - 重新格式化 SymPy 中的表达式片段以防止常数系数的分布

python - Google App Engine ndb 按 StringProperty 长度排序

java - 将 HTTPServletRequest 流写入 Google App Engine 的数据存储区

python - 为什么 pickle 吃内存?

java - 如何在 JUnit 测试中引发 DatastoreTimeoutException 或/和 DatastoreFailureException?

java - 如何从一个进程返回到一个前端后端进程?

python - 一次性将大量数据导入 Google App Engine 数据存储

google-app-engine - XG-Transactions 在 Google App Engine 的本地 Java 服务器中失败——部署在 Live GAE 上时运行良好

python - Numpy 标准差属性错误 : 'Float' object has no attribute 'sqrt'