I am trying to make a python file into a python and html files. The code i have is basically from the python guestbook example but i want to have a html file serve the uses browser. the code i have works right now but when i add the javascript at the bottom i get an error This code is at ceemee11111.appspot.com
import cgi
import datetime
import urllib
import webapp2
from google.appengine.ext import db
from google.appengine.api import users
class Greeting(db.Model):
"""Models an individual Guestbook entry with an author, content, and date."""
author = db.StringProperty()
content = db.StringProperty(multiline=True)
content2 = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
def guestbook_key(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):
self.response.out.write('<html><body>')
guestbook_name=self.request.get('guestbook_name')
greetings = db.GqlQuery("SELECT * "
"FROM Greeting "
"WHERE ANCESTOR IS :1 "
"ORDER BY date DESC LIMIT 3",
guestbook_key(guestbook_name))
self.response.out.write("""
<form action="/sign?%s" method="post">
<div id="container" style="width:800px">
<div id="header" style="background-color:#FFA500;">
<h1 style="margin-bttom:0;">Main Title</h1></div>
<div id="Con0" style="background-color:#FFD700;
height:200px;width:200px;float:left;">
<b>Menu</b><br>
HTML<br>
CSS<br>
<p id="demo1"></p><br>
JavaScript</div>
<div id="content" style="background-color:#EEEEEE;height:200px;width:600px;float:left;">
Content goes here</div>
</div>
<button onclick="myFunction()">Try it</button>
</form>
</body>
</html>""")
self.response.out.write("""
<form action="/sign?%s" method="post">
<div id="dataImput"
<div><textarea name="content" rows="1" cols="10"></textarea></div>
<div><textarea name="content2" rows="1" cols="10"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</div>
</form>
<hr>
<form>Guestbook name: <input value="%s" name="guestbook_name">
<input type="submit" value="switch"></form>
</body>
</html>""" % (urllib.urlencode({'guestbook_name': guestbook_name}),
cgi.escape(guestbook_name)))
class Guestbook(webapp2.RequestHandler):
def post(self):
# 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=guestbook_key(guestbook_name))
if users.get_current_user():
greeting.author = users.get_current_user().nickname()
greeting.content = self.request.get('content')
greeting.content2 = self.request.get('content2')
greeting.put()
self.redirect('/?' + urllib.urlencode({'guestbook_name': guestbook_name}))
app = webapp2.WSGIApplication([('/', MainPage),
('/sign', Guestbook)],
debug=True)
#<script>
#function myFunction()
#{
#document.getElementById("demo1").innerHTML="test";
#}
Thankyou for your time.
Dan
Given that you're clearly using GAE, what you are looking to do is outlined here.
First, move your html to separate files. We'll start with the html from the oddly freefloating self.response.out.write:
"""
<form action="/sign?%s" method="post">
<div id="dataImput"
<div><textarea name="content" rows="1" cols="10"></textarea></div>
<div><textarea name="content2" rows="1" cols="10"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</div>
</form>
<hr>
<form>Guestbook name: <input value="%s" name="guestbook_name">
<input type="submit" value="switch"></form>
</body>
</html>""" % (urllib.urlencode({'guestbook_name': guestbook_name}),
cgi.escape(guestbook_name))
This belongs in a separate file we'll call myhtml.html. Second, we then are going to go through and using the Django templating system instead of %s and Python string formatting. So first, we're going to replace the %s with template-friendly fields surrounded by {{ }}, giving us:
"""
<form action="/sign?{{ guestbook_name }}" method="post">
<div id="dataImput"
<div><textarea name="content" rows="1" cols="10"></textarea></div>
<div><textarea name="content2" rows="1" cols="10"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</div>
</form>
<hr>
<form>Guestbook name: <input value="{{ guestbook_name|escape }}" name="guestbook_name">
<input type="submit" value="switch"></form>
</body>
</html>"""
Note that we were able to use the escape template filter, which is what comes after the |, to escape the value we're getting from guestbook_name.
Finally, we load the html and pass it the arguments we need:
self.response.out.write(template.render('myhtml.html', {'guestbook_name': guestbook_name}))
I think your code will really benefit from separating the HTML from the Python code.
You can do that by writing an html template and use jinja2 (which comes with google appengine) to generate the html. There are instructions on how to do that here. The JavaScript would go in the HTML template, not in the Python code.
Related
Getting a 400, when trying to upload a file ad send other form elements to flask from html. Tried to use ajax, but that throws me an error as well.
Python:
#app.route('/prod_diff_result', methods=['POST', 'GET'])
def prod_diff_result():
try:
host = request.form['host-prod-iterator']
print(host)
if request.files['file']:
f = request.files['file']
f.save(secure_filename(f.filename))
HTML:
<div class="main-div">
<form action="/prod_diff_result" method="POST" enctype="multipart/form-data">
<div class="grid-container">
<div class="grid-item">
<span class="label label-default ">PROD</span><br>
<p>Iterator Host : <input type="text" class="form-control" id="host-prod-iterator" value="10.47.7.57"
required></p>
<input type="radio" name="data_fetch_type" value="file" onclick="showfile()">Upload File
<input type="file" name="file" />
<input type="radio" name="data_fetch_type" value="db"> Get from DB
<input type="submit" />
</div>
</form>
</div>
I want to be able send hostname and file back to flask error in one request and using one form.
It gives an error because you try to access a form field that it cannot find, and assumes that somehow the request was bad, because it didn't include a required form field. You are trying to access:
host = request.form['host-prod-iterator']
However you have simply not given it a name in your HTML. If you give it a name, it should work:
<p>Iterator Host :
<input type="text" class="form-control" name="host-prod-iterator" id="host-prod-iterator" value="10.47.7.57" required>
</p>
screenshot of the outputI'm looking to get posts from a user to post on individual lines. At the moment I take in a name, email and comment, pass it to the app.py file and store it to a text file. I return a name, email, comment and the time of the comment. When I read the file and pass in back to the html template the posts display one after the other (see the screenshot included), and im trying to have them display one below each other. f.write("\n") results in the actual text file skipping a line however this does not occur in the template.
form_action.html
<html>
<div align = "center">
<body style="background-color: #3DC247;">
<head>
<title>Conor McGregor</title>
</head>
<body>
<div align = "center">
<h1 style="font-family:verdana;">I AM EL CHAPO</h1>
<div align = "center">
<h2 style="font-family:verdana;">YOU'LL DO NUTIN.</h2>
<div align = "center">
<h2 style="font-family:verdana;">Disscusion Page</h2>
<body>
<div id="container">
<div class="title">
<h3 style="font-family:verdana;">Please fill in your details
below and your comment to join the discussion</h3>
</div>
<div id="content">
<form method="post" action="{{ url_for('hello') }}">
<label for="yourname" style="font-family:verdana;">Please
enter your name:</label>
<input type="text" name="yourname" /><br /><br>
<label for="youremail" style="font-family:verdana;">Please
enter your email:</label>
<input type="text" name="youremail" /><br /><br>
<label for="yourcomment"style="font-family:verdana;">Please
enter your comment:</label>
<input type="textarea" name="yourcomment" rows="4" cols="50">
<input type="submit" /><br>
</form>
</div>
</div>
</div>
</div>
<div id="container">
<div class="title">
<h1 style="font-family:verdana;"><p>Comments</p></h1>
</div>
<div id="content">
{{details}}
</div>
</div>
</body>
</html>
app.py
from flask import Flask, render_template, request, url_for
import time
import datetime
# Initialize the Flask application
app = Flask(__name__)
# Define a route for the default URL, which loads the form
#app.route('/')
def form():
return render_template('form_submit.html')
#app.route('/hello/', methods=['POST','GET'])
def hello():
global time
name=request.form['yourname']
email=request.form['youremail']
comment=request.form['yourcomment']
comment_time=time.strftime("%a-%d-%m-%Y %H:%M:%S")
f = open ("user+comments.txt","a")
f.write(name + ' ' + email + ' ' + comment + " " + comment_time)
f.write('\n')
f.close()
with open("user+comments.txt", "r") as f:
details = f.read()
f.close()
return render_template('form_action.html', details = details, name=name,
email=email, comment=comment, comment_time=comment_time)
if __name__ == '__main__':
app.run(debug=True)
HTML does not know what \n is. You can fix this in two ways.
Convert str details to list details
details = f.read().split('\n')
This converts the str object to list object. You could print it in your template using
{% for detail in details %}
{{detail}}
{% endfor %}
Replace \n with <br>
details = f.read().replace('\n','<br>')
and then print it as {{ details|safe }} in form_action.html.
It is important that you use the safe filter. The <br> would be escaped without it and rendered as simple text.
My goal is to run python function when a user clicks on a button within a form on my web page, when the argument is taken from textarea HTML element.
The following html code is my form with button within and is part of django application.
<div id="contact_form" class="col_400 float_l">
<form id="demoForm" name="contact" >
<label for="text">Your Review:</label>
<textarea id="text" name="text" rows="0" cols="0" class="required"></textarea>
<div class="cleaner_h10"></div>
<input type="button" onclick="return Button1_onclick()" class="submit_btn float_l" name="submit" id="predictSentBtn" value="Predict" />
</form>
</div>
I looked on django.forms and django.forms.widgets, but still don't understand how to "link" between existing html elements and python objects.
This should help:
<div id="contact_form" class="col_400 float_l">
<form id="demoForm" name="contact" >
<label for="text">Your Review:</label>
<textarea id="needid" name="needid" rows="0" cols="0" class="required"></textarea>
<div class="cleaner_h10"></div>
<input type="button" onclick="return Button1_onclick()" class="submit_btn float_l" name="submit" id="predictSentBtn" value="Predict" />
</form>
def function(request):
if request.method = 'POST':
print request.POST['needid'] # print request.POST.get('needid')
Try it ;)
Trying to upload multiple files at once using python. The upload.html source code is as followed:
<form name="frmRegister" method="post" accept-charset="utf-8" enctype="multipart/form-data" class="form-horizontal">
<div class="control-group">
<div class="controls">
<input type="file" name="files" multiple='multiple'>
</div>
</div>
<div class="control-group">
<div class="controls">
<input class="btn btn-primary" type="submit" name="btnSubmit" value="Add Product" />
</div>
</div>
</form>
in my admin.py:
#view_config(context="mycart:resources.Product", name="add", renderer='admin/mall/product/add.jinja2', permission = 'admin')
#view_config(context="mycart:resources.Product", name="add", request_method="POST", renderer='admin/mall/product/add.jinja2', permission = 'admin')
def product_add(context, request):
if 'btnSubmit' in request.POST:
print ("files >>> ", request.POST['files'])
in my terminal, it is showing just FieldStorage('files', u'DSC01973.JPG') whereas I've selected 'DSC01975.JPG', 'DSC01976.JPG'.
Why is this so?
I've found a way to solve it, I believe there are many others, if there are, please feel free to holler out:
fileslist = request.POST.getall('files')
print ("My files listing: ", fileslist)
for f in fileslist:
print ( "individual files: ", f )
I could solve the problem with the following function:
from cgi import FieldStorage
def get_all_file_data_list(request):
return [x for x in request.POST.values() if isinstance(x, FieldStorage)]
This is the Html form:
<form action='use.py'>
<div><input type='text' name='etc'></div>
<p><input type='submit' value='etc!'></p>
</form>
And this is the python for it
colour = form["colour"].value
The top html form is a text box that users can type something in.
If I were to have a drop down box / radio button form like this:
<form action='etc.py'>
<p>List Type:</p>
<div><input type='radio' name='status' value='bulleted' checked>
Bulleted
</div>
<div><input type='radio' name='status' value='numbered'>
Numbered
</div>
<p>Text style:</p>
<div><input type='checkbox' name='bold'>
<b>Bold</b>
</div>
<div><input type='checkbox' name='italic'>
<i>Italic</i>
</div>
<p>Movies to display:</p>
<div>
<select name='type'>
<option>Only numbers</option>
<option>Only names</option>
</select>
</div>
<p><input type='submit' value='Display'></p>
</form>
How would I write my python? Like this?
only_numbers = form["Only numbers"].value
You can write a Python CGI script, but most Python frameworks are built upon WSGI and have a concept of request/response objects. For example, in Django the value would be available at request.POST['fieldname'].
Using the python CGI module, it is like:
form = cgi.FieldStorage()
# for multiple elements with same name or elements with multiple values
a_list = form.getlist("multiple_select_input")
# For single value elements
if "single_value_input" in form:
x = form["single_value_input"].value
else:
x = "default value"
# or
x = form.getvalue("single_value_input", "default value")