POST request of rot13 app breaking my app - google-app-engine

I am following the tutorials on Udacity.com to learn web development and I currently have to build a rot13 app on Google App Engine..
My entire code is shown below even though I believe the error is from POST function.
If I comment it out I'm able to see the app even though can't do anything it.
But if I uncomment it, it shows a blank page in my browser.
Hoping to get some pointers on what I'm doing wrong here. Thanks in advance
import webapp2
import cgi
form="""<html>
<head>
<title>Unit 2 Rot 13</title>
</head>
<body>
<h2>Enter some text to ROT13:</h2>
<form method="post">
<textarea name="text" style="height: 100px; width: 400px;"> </textarea>
<br>
<input type="submit" value="submit">
</form>
</body>
</html>
"""
def rot13(a):
list1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
list2 = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM'
result = ''
for e in a:
if e in list1:
result = result + list2[list1.find(e)]
else:
result = result + e
return result
def escape_html(s):
return cgi.escape(s, quote = True)
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.out.write(form)
def post(self):
rot13 = ''
text = self.request.get('text')
if text:
rot13 = text.encode('rot13')
self.response.out.write(form, text = rot13)
application = webapp2.WSGIApplication([('/', MainPage)], debug=True)

Related

How to access the checkbox data in Django form

I have a few checkboxes in my Django form. After a user selects a particular checkbox, I want to know which all checkboxes were selected by the user. I can see the first name, last name, username, and email of the user in the Django admin, that the user provides while filling up the form, but I can't see which checkboxes did the user select.
How can I access the Checkbox's data? I know I need to do some modifications in my code for that, so please suggest me the modifications in my code. I'm using Django 1.9.I went through some materials online and the documentation as well, but couldn't understand much.
forms.py
from django import forms
from django.contrib.auth.models import User
from volunteer.models import UserProfileInfo
NGO_CHOICES = (
('one', 'ONE'),
('two', 'TWO'),
('three', 'THREE'),)
class UserForm(forms.ModelForm):
ngo = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
choices=NGO_CHOICES)
class Meta():
model = User
fields = ('ngo','email','first_name','last_name','username')
views.py
from django.shortcuts import render
from volunteer.forms import UserForm
def register(request):
registered = False
if request.method =="POST" :
user_form = UserForm(data=request.POST)
if user_form.is_valid():
ngo = user_form.cleaned_data['ngo'] #getting the list of the ngos.
user = user_form.save()
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserForm()
return render(request, 'volunteer/volunteer.html',
{'user_form':user_form,
'registered':registered})
models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfileInfo(models.Model):
user=models.OneToOneField(User)
def __str__(self):
return self.user.first_name
return self.user.last_name
return self.user.email
return self.user.ngo
admin.py
from django.contrib import admin
from volunteer.models import UserProfileInfo
# Register your models here.
admin.site.register(UserProfileInfo)
urls.py
from django.conf.urls import url
from . import views
app_name = 'volunteer'
urlpatterns = [
url(r'^', views.register, name='register'),
]
volunteer.html(which has the form)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
</head>
<body>
<div class="jumbotron">
{% if registered %}
<p>Thank you.<p>
{% else %}
<h1>Register yourself for Volunteering</h1>
<form method="post">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" name="" value="Register as a Volunteer">
{% endif %}
</div>
</form>
</body>
</html>
NOTE - I haven't included bootstrap, ajax and jquery libraries in the above HTML code due to formatting issues, I don't think they have anything to do with the problem, so.
You can access in your view all data from your forms.
Just print request.POST to see wich checkbox is selected.

How to add Checkboxes in Django Form.

I want to add checkboxes in my Django form for different NGOs(say NGO1, NGO2, and so on...). I want the user to select those checkboxes and that data should be saved in the database.
Please, Suggest me the necessary changes in the code. I'm using Django 1.9.
models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfileInfo(models.Model):
user=models.OneToOneField(User)
def __str__(self):
return self.user.first_name
return self.user.last_name
return self.user.email
forms.py
from django import forms
from django.contrib.auth.models import User
from volunteer.models import UserProfileInfo
class UserForm(forms.ModelForm):
class Meta():
model = User
fields = ('email','first_name','last_name','username')
views.py
from django.shortcuts import render
from volunteer.forms import UserForm
def register(request):
registered = False
if request.method =="POST" :
user_form = UserForm(data=request.POST)
if user_form.is_valid():
user = user_form.save()
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserForm()
return render(request, 'volunteer/volunteer.html',
{'user_form':user_form,
'registered':registered})
admin.py
from django.contrib import admin
from volunteer.models import UserProfileInfo
# Register your models here.
admin.site.register(UserProfileInfo)
urls.py
from django.conf.urls import url
from . import views
app_name = 'volunteer'
urlpatterns = [
url(r'^', views.register, name='register'),
]
volunteer.html(which has the form)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content = "width=device-width, initial-scale=1.0">
</head>
<body>
<div class="jumbotron">
{% if registered %}
<p>Thank you <p>
{% else %}
<h1>Register yourself for Volunteering</h1>
<form method="post">
{% csrf_token %}
{{ user_form.as_p }}
<input type="submit" name="" value="Register as a Volunteer">
{% endif %}
</div>
</form>
</body>
</html>
NOTE - I haven't included bootstrap, ajax and JQuery libraries in the above html code due to the formatting issues, I think it has nothing to do with the problem, so.
Thanks in advance!
You can easily achieve that using checkbox widget in django forms.
Define your form class as :
NGO_CHOICES = (
('one', 'ONE'),
('two', 'TWO'),
('three', 'THREE'),)
class UserForm(forms.ModelForm):
ngo = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple,
choices=NGO_CHOICES)
class Meta():
model = User
fields = ('ngo', 'email','first_name','last_name','username')
Now while saving the data, you can access the data of checkbox in
if request.method =="POST" :
user_form = UserForm(data=request.POST)
if user_form.is_valid():
# getting the list of ngos
ngo = user_form.cleaned_data['ngo']
user = user_form.save()
user.save()
registered = True
else:
print(user_form.errors)
else:
user_form = UserForm()
Hope it helps.

Why are my search results not displayed?

When I make I search in my web form, it appears that matches are found but they are not displayed:
What can I do to make the SERP display? My code is:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/static/css/main.css"/>
<title>Search Demonstration App</title>
</head>
<body>
<form action="/sign" method="post">
<div>Search Demo</div>
<div><textarea name="search" rows="1" cols="60"></textarea></div>
<div><input type="submit" value="Search"/></div>
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Comment"/></div>
</form>
{{number_returned}} of {{results.number_found}} comments found <p>
{% for scored_document in results %}
{% for field in scored_document.fields %}
{{field.value}}
{% endfor %}
<p>
{% endfor %}
{{ url_linktext }}
</body>
</html>
And .py
class SearchAPI(webapp.RequestHandler):
"""Handles search requests for comments."""
def get(self):
"""Handles a get request with a query."""
uri = urlparse(self.request.uri)
query = ''
if uri.query:
query = parse_qs(uri.query)
query = query['query'][0]
# sort results by author descending
expr_list = [search.SortExpression(
expression='author', default_value='',
direction=search.SortExpression.DESCENDING)]
# construct the sort options
sort_opts = search.SortOptions(
expressions=expr_list)
query_options = search.QueryOptions(
limit=3,
sort_options=sort_opts)
query_obj = search.Query(query_string=query, options=query_options)
results = search.Index(name='ad').search(query=query_obj)
#logging.info("number of results:" +len(results))
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'
template_values = {
'results': results,
'number_returned': len(results.results),
'url': url,
'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), 'searchapi.html')
self.response.out.write(template.render(path, template_values))
The index is built like this:
class CreateAdHandler(BaseHandler):
def post(self):
ad = Ad.get_by_id(self.session.get('ad_id'))
city_entity = montaomodel.City.all().filter('name =', ad.city).get()
region_entity = montaomodel.Region.all().filter('name =', ad.region).get()
form = PreviewAdForm(self.request.params)
if form.validate():
ad.set_password(self.request.get('password'))
ad.published = True
ad.put()
doc = search.Document(doc_id=str(ad.key()),
fields=[search.TextField(name='title',
value=ad.title),search.TextField(name='text',
value=ad.text),search.TextField(name='city',
value=ad.city),search.TextField(name='region',
value=ad.region),search.NumberField(name='cityID',
value=city_entity.key().id()),search.NumberField(name='regionID',
value=region_entity.key().id()),search.NumberField(name='category',
value=int(ad.category)), search.NumberField(name='constant',
value=1), search.NumberField(name='adID',
value=ad.key().id()),
search.TextField(name='name',
value=ad.name
)],
language='en')
search.Index(name='ad').add(doc) # should this be "put" instead? see https://developers.google.com/appengine/docs/python/search/overview#Deleting_Documents
self.redirect('/vi/%d.html' % (ad.key().id(), ))
else:
logging.info('form did not validate')
self.render_jinja('preview', form=form, ad=ad)
Update
By careful debugging it's shown that this line won't work: {% for f in scored_document.fields %}. I found by debugging but I don't know why. So at least I'm closer to the solution now but it's not done.
Update 2
I can't understand why the fields are not accessed. I can add and output the data to the console:
INFO 2013-05-14 01:00:53,944 main.py:4437] result: search.ScoredDocument(doc_id=u'eb24f746-c60a-462c-9f64-a06ad6a823cb', fields=[search.TextField(name=u'author', value=u'test'), search.TextField(name=u'comment', value=u'test'), search.DateField(name=u'date', value=datetime.datetime(2013, 5, 13, 0, 0))], language=u'en', rank=74648319L)
INFO 2013-05-14 01:00:53,944 main.py:4437] result: search.ScoredDocument(doc_id=u'af0de892-0e59-4c12-bd9e-6e8caa2067d4', fields=[search.TextField(name=u'author', value=u'test'), search.TextField(name=u'comment', value=u'test'), search.DateField(name=u'date', value=datetime.datetime(2013, 5, 14, 0, 0))], language=u'en', rank=74653247L)
This logging takes place like this now:
for r in results:
logging.info("result: " + str(r))
So if I can log data like that to the console, why can't I just output it to my page?
Seems like you should iterate through results.results in your template:
{% for scored_document in results.results %}
I think you need to include the returned_fields property in your QueryOptions. (A list of field-names.)

How to access html array from template on the server side (python) - Google App Engine

sorry if this question is basic but I'm a beginner :(.
I've created an array in my html template (via javascript) and user can enter multiple values for this input --- how do I then access the array from server side (python Google App Engine?)
Here's my code from html template
JS:
<script type="text/javascript">
function addSchool() {
var newContent = "<input type='text' name='institution[]'></input>";
$("#providerList").append(newContent);};
HTML:
{% for s in list %}
<div id="institution" name="institution[]">{{s}}</div>
{% endfor %}
<div id="onemore">
<a href='javascript:addSchool()'>Add More Institutions as Providers</a>
</div>
Then my server side retrieving the array - python in Google App Engine: - (which is NOT WORKING) - only retrieves 1st one:
mylist = self.request.get("institution[]")
What am I do doing wrong syntax wise to retrieve the array???
You have to create form elements which can be submitted, like an input, or select option tags.
Or you have to create a json string and post the serialized json (javascript object) as a string.
Or you create your own string by concatenating the list elements and use it as payload for your post.
Example :
<form action="/addschool" method="post">
<input type="hidden" name ="more" value="school10,school11, school12" >
<input class="button" type="submit" id="addschool" name="addschool" value="Add a school">
</form>
Now you can:
mylist = self.request.get("more").split(',')

UnicodeDecodeError. While rendering the blob image

I am trying to add uploading images feature.
This class saves new entity:
class NewPost(Handler):
def render_newpost(self, title='' , content='', error = ''):
self.render("newpost.html", title = title, content = content, error = error)
def get(self):
user_cookie = self.request.cookies.get('user')
if user_cookie:
user_id = user_cookie.split('|')[0]
if hash_str(user_id) == user_cookie.split('|')[1]:
user = Users.get_by_id(int(user_id))
self.render_newpost()
else:
self.redirect('/')
def post(self):
title = self.request.get("title")
content = self.request.get("content")
image = self.request.get("file")
if title and content:
p = Posts(title = title, content = content)
p.image=db.Blob(image)
p.put()
self.redirect("/")
else:
error = "Enter both title and text"
self.render_newpost(title, content, error)
Here is my front page render class:
class Main(Handler):
def get(self):
posts = db.GqlQuery("SELECT * FROM Posts Order by created DESC LIMIT 10")
user_cookie = self.request.cookies.get('user')
if user_cookie:
user_id = user_cookie.split('|')[0]
if hash_str(user_id) == user_cookie.split('|')[1]:
user = Users.get_by_id(int(user_id))
self.render("front.html", posts = posts, user=user)
else:
self.response.headers['Content-Type'] = "image/jpeg"
self.render("front.html", posts = posts)
form to enter data:
<form method="post" enctype="multipart/form-data">
<div class="newpost">
<label>Image:</label>
<input type="file" name="file"/>
<div class="label">Title:
<input type="text" name="title" value="{{title}}"/>
</div>
<hr>
<div class="label">Content:
<textarea name="content">{{content}}</textarea>
</div>
</div>
<input type="submit"/>
<div class="error">{{error}}</div>
</form>
and here is my home page template: (The problem appears here!)
{% for post in posts %}
{% if post.image %}
<li><img src="/static/images/{{post.image}}"/>
{% endif %}
<h4>{{post.title}}</h4>
<p class="zoom">{{post.content}}</p>
{% endfor %}
App successfully stores image, but when it returns to the front page trying to render image it gives this error:
File "/home/wanhrust/google_appengine/newsite/templates/front.html", line 54, in top-level template code
{{post.image}}
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)
I've been googling for several hours but without results. Any help?
The problem is that you are trying to embed an image in an html document which is not possible. Post.image is storing the bytes representing the image.
If you want to include the image in your html, you need to add something like this
{% if post.image_id %}
<li><img src="/image/{{post.image_id}}" />
{% endif %}
Where /image/ is a handler that returns the content of the image (setting the apprpriate content-type).
I also would recommend you to use the Blobstore API.

Resources