我有一个 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/