Reputation: 55
I want to save checkbox value to a db and use them in google appengine project. my previous question was about storing this to a session. I modified this simple google project by that. but cant get this work. It saves guestbook entries but not checkboxes.
here is html:
<html>
<body>
{% for greeting in greetings %}
{% if greeting.author %}
<b>{{ greeting.author }}</b> wrote:
{% else %}
An anonymous person wrote:
{% endif %}
<blockquote>{{ greeting.content|escape }}</blockquote>
{% endfor %}
<form action="/sign" method="post">
<input type="checkbox" id="opt1" name="option 1" {% if not greetings.opts or "option 1" in greetings.opts %}checked="1"{% endif %} /><span class="font90" style="cursor:default;" >{{("Option 1")}} </span>
<input type="checkbox" id="opt2" name="option 2" {% if not greetings.opts or "option 2" in greetings.opts %}checked="1"{% endif %} /><span class="font90" style="cursor:default;" >{{("Option 2")}}</span>
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<a href="{{ url }}">{{ url_linktext }}</a>
<br>
<br>
<br>
</body>
</html>
and helloword.py:
import urllib
import webapp2
from google.appengine.ext import db
from google.appengine.api import users
import jinja2
import os
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class Greeting(db.Model):
"""Models an individual Guestbook entry with an author, content, and date."""
opts=db.StringListProperty()
author = db.StringProperty()
content = db.StringProperty(multiline=True, indexed=False)
date = db.DateTimeProperty(auto_now_add=True)
def _GuestbookKey(guestbook_name=None):
"""Constructs a Datastore key for a Guestbook entity with guestbook_name."""
return db.Key.from_path('Guestbook', guestbook_name or 'default_guestbook')
class MainPage(webapp2.RequestHandler):
def get(self): # pylint:disable-msg=invalid-name
"""Handle GET requests."""
guestbook_name = self.request.get('guestbook_name')
greetings_query = Greeting.all().ancestor(
_GuestbookKey(guestbook_name)).order('-date')
greetings = greetings_query.fetch(10)
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
## opt=self.request.get('opts',[])
template_values = {
'greetings': greetings,
'url': url,
'url_linktext': url_linktext,
}
## 'opts': dict.fromkeys(opt, 'checked')
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render(template_values))
class Guestbook(webapp2.RequestHandler):
def post(self): # pylint:disable-msg=invalid-name
"""Handle POST requests."""
# We set the same parent key on the 'Greeting' to ensure each greeting is in
# the same entity group. Queries across the single entity group will be
# consistent. However, the write rate to a single entity group should
# be limited to ~1/second.
guestbook_name = self.request.get('guestbook_name')
greeting = Greeting(parent=_GuestbookKey(guestbook_name))
if users.get_current_user():
greeting.author = users.get_current_user().nickname()
allopts=['option 1','option 2','option 3']
greeting.opts=[op for op in allopts if self.request.get(op)]
## greeting.opts=self.request.get("opts", allow_multiple=True)
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/?' + urllib.urlencode({'guestbook_name': guestbook_name}))
APP = webapp2.WSGIApplication([
('/', MainPage),
('/sign', Guestbook),
], debug=True)
Upvotes: 0
Views: 147
Reputation: 882241
Despite all of its remaining defects this code after the edits does save a list of checked checkboxes -- it never shows them because in the template it checks greetings.opts
, which does not exist, instead of checking greeting.opts
(no s
just before the .
) inside the loop where greeting
, singular, is defined.
So e.g changing the heart of the template to
{% for greeting in greetings %}
{% if greeting.author %}
<b>{{ greeting.author }}</b> wrote:
{% else %}
An anonymous person wrote:
{% endif %}
<blockquote>{{ greeting.content|escape }}</blockquote>
<input type="checkbox" name="option 1" {% if not greeting.opts or "option 1" in greeting.opts %}checked="1"{% endif %} /><span class="font90" style="cursor:default;" >{{("Option 1")}} </span>
<input type="checkbox" name="option 2" {% if not greeting.opts or "option 2" in greeting.opts %}checked="1"{% endif %} /><span class="font90" style="cursor:default;" >{{("Option 2")}}</span>
<p><p>
{% endfor %}
<p><p>
<form action="/sign" method="post">
will display right after each greeting two checkboxes set or unset depending on how they were when the form for that greeting was submitted.
There are many small remaining issues (e.g strictly speaking it's wrong HTML to have checked=1
, but browsers typically ignore those mistakes), of which the worst one is using ancient db
rather than nice new ndb
.
But, this change in the template (plus all the bugs I had previously mentioned in my comments and your edits have now fixed) does seem to answer the question as it stands.
Upvotes: 1