私はPythonとGAEに不慣れで、例を通して自分のプロジェクトのタスクキュー、cron、データストアを操作する方法を学ぼうとしていますが、まったく運がありませんでした。YouTubeのこのGoogleDevelopersチュートリアルビデオから Votelatorコードを変更しようとしています: http ://www.youtube.com/watch?v = AM0ZPO7-lcE ここで動作しているのを見ることができます:http://voterlator.appspot.com/
コードが完全ではないことに気付いたので、何が欠けているのかを理解しようと決心しました。私はいくつかの代用をしました(例えば、プログラミング言語は現在乳製品です)。チュートリアルコードで解決されていないことがいくつかあります。たとえば、変数LANGUAGESはどこにも指定されていません。データモデルがフォームから言語の値を取得し、それらをキーとして使用する方法は私にはわかりません。
なぜ機能しないのかわかりません。私はそれを機能させるために試みたコードのいくつかをそこに残し、それをコメントアウトしました。
app.yamlは次のとおりです。
application: voting
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /static/css
static_dir: static/css
- url: /static/css/sunny
static_dir: static/css/sunny
- url: /static/js
static_dir: static/js
- url: /cron/tally
script: main.app
- url: /.*
script: main.app
cron.yamlは次のとおりです。
cron:
- description: vote tallying worker
url: /cron/tally
schedule: every 1 minutes
これはqueue.yamlです
total_storage_limit: 120M
queue:
- name: votes
mode: pull
これはmain.pyです
import webapp2
from google.appengine.ext import db
from google.appengine.api import taskqueue
import os
import jinja2
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class Tally(db.Model):
"""Counting model"""
count = db.IntegerProperty(default=0, required=True)
#key_name = ['Milk', 'Butter', 'Cheese'] #added
#key_name = db.StringProperty(choices=set(['Milk', 'Butter', 'Cheese'])) #added
cls = ['Milk', 'Butter', 'Cheese'] #added
@classmethod
def increment_by(cls, key_name, count):
"""Increases a tally's count. Should be run in a transaction."One tally for each language"""
"""The key_name is going to be the language name"""
"""There's a convenience method there that actually will update the count"""
tally = cls.get_by_key_name(key_name)
if tally is None:
tally = cls(key_name=key_name)
tally.count += count
tally.put()
#db.run_in_transaction(increment_by, key_name, count) #added
#db.run_in_transaction(cls, key_name, count) #added
#db.run_in_transaction(Tally.increment_by, cls, count) #added
class VoteHandler(webapp2.RequestHandler):
"""Handles adding of vote tasks"""
def get(self):
"""Displays the voting form"""
tally_query = Tally.all() #added
#tally_query = Tally.all(key_name) #added
tallies = tally_query.fetch(3) #added
urla = '_ah/admin/'
url_admin = 'Admin'
urlvh = '/'
url_votehand = 'Votes'
ugliest = self.request.get('ugliest')
template_values = {
'tallies': tallies, #added
'ugliest': ugliest, #added
'url_admin': url_admin,
'urla': urla,
'urlvh': urlvh,
'url_votehand': url_votehand,
}
template = jinja_environment.get_template('vote_handler.html')
self.response.out.write(template.render(template_values))
def post(self):
"""Adds to the votes queue if ugliest is valid. """
LANGUAGES = ['Milk', 'Butter', 'Cheese'] #added: This is just a guess
ugliest = self.request.get('ugliest')
if ugliest and ugliest in LANGUAGES: ### No variable specified for LANGUAGES
q = taskqueue.Queue('votes')
q.add(taskqueue.Task(payload=ugliest, method='PULL'))
self.redirect('/')
#db.run_in_transaction(Tally.increment_by(cls, key_name, count)) #added
class TallyHandler(webapp2.RequestHandler):
def post(self):
"""Leases vote tasks, accumulates tallies and stores them"""
q = taskqueue.Queue('votes')
# Keep leasing tasks in a loop.
while True:
tasks = q.lease_tasks(300, 1000)
if not tasks:
return
# accumulate tallies in memory
tallies = {}
for t in tasks:
tallies[t.payload] = tallies.get(t.payload, 0) + 1
self.store_tallies(tallies)
q.delete_tasks(tasks)
app = webapp2.WSGIApplication([('/', VoteHandler),
('/cron/tally', TallyHandler)], #called from cron, pulls votes from the queue and updating tallies
debug=True)
def main():
app.run()
if __name__ == "__main__":
main()
これは、vote_handler.htmlのフォームのコードです。
<form action="/" method="post">
<input type="radio" name="ugliest" value="Milk" /> Milk<br>
<input type="radio" name="ugliest" value="Butter" /> Butter<br>
<input type="radio" name="ugliest" value="Cheese" /> Cheese
<br>
<div>
<input type="submit" value="Submit">
</div>
</form>
<div class="commentary">
{% for tally in tallies %}
{{ tally.count }}
{% endfor %}
</div>
フォームのすぐ下に結果を表示するようにしようとしました。
最終的に発生するのは、フォームがキューにタスクを追加し、データストアにタスクの種類がありますが、エンティティが含まれていないことです。何が悪いのかわかりません。