Web Page Not Reloading - python

I am executing the following code.
import webapp2
form="""
<form method = "post">
What is your birthday?
<p>
<label>
Day
<input type = "text" name = "day">
Month
<input type = "text" name = "month">
Year
<input type = "text" name = "year">
</p>
<input type = "submit">
</form>
"""
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write(form)
def post(self):
self.response.out.write(form)
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
When I try opening the page localhost:8080, I do not see anything. The page is empty.

I am not familiar with webapp2 but:
after a quick look to tutorials I have seen them write:
self.response.write(...) instead of self.response.out.write()
your code is not correctly indented, you should have:
def get(self):
self.response.write(form)
the string "form" does not seem like a valid html page
maybe you could try
<!DOCTYPE html>
<html>
<head>
<title>Whatever</title>
</head>
<body>
<form method = "post">
What is your birthday?
<p>
<label>
Day
<input type = "text" name = "day">
Month
<input type = "text" name = "month">
Year
<input type = "text" name = "year">
</p>
<input type = "submit">
</form>
</body>
</html>

Related

Python Flask - Make uploaded "file chosen" name stick on the HTML page

I have two input buttons. One is for uploading a file, and the other one is a submit button that adds the uploaded file to the database.
My problem is, after I submit the file, the first button that's used for uploading goes back to "No file chosen" next to the button. However, I want the uploaded file name to "stick" to the UI/html page as the file chosen.
Here is my File class:
class Files(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True, nullable=False)
data = db.Column(db.LargeBinary)
Here is my HTML code:
<td>
<form class="" action="{{url_for('main.upload_file')}}" method="post" enctype="multipart/form-data">
<input type="hidden" name="id" value="{{row.id}}">
<input style="margin-bottom: 5px;" type="file" accept=".csv" name="csvfile" id="upload" value ="{{row.name}}"> <br>
<input style="margin-bottom: 10px;" type="submit" name="" value="Submit"> <br>
</form>
<a href={{ url_for('main.files') }}>Go to Downloads Page</a>
<br>
</td>
I've tried making the value attribute equal to the file name getting passed in ex. value ="{{row.name}}" for the file type <input> above, but that doesn't keep the file chosen name on the page after submission either. I can't find any videos or posts that deal with this problem, so I would really appreciate any guidance. TIA!
I think setting a default value for an input field of type file is forbidden for security reasons.
However, if you want to keep the name of the selected file, you can aim for a transfer with AJAX. Here you can suppress the standard behavior of the form. The page is not reloaded and the form is not reset.
The example below shows you how it works.
Flask (app.py)
from flask import Flask
from flask import (
render_template,
request,
)
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload-file', methods=['POST'])
def upload_file():
if 'csvfile' in request.files:
file = request.files['csvfile']
if file.filename != '':
# handle file here!
return '', 200
return '', 400
HTML (templates/index.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form name="my-form" method="post">
<input type="file" name="csvfile" />
<input type="submit" />
</form>
<script type="text/javascript">
((uri) => {
const elem = document.querySelector('form[name="my-form"]');
elem.addEventListener('submit', evt => {
evt.preventDefault();
const formData = new FormData(evt.target);
fetch(uri, {
method: 'post',
body: formData
}).then(resp => {
if (resp.status === 200) {
console.log('Submit successful.');
}
});
})
})({{ url_for('.upload_file') | tojson }});
</script>
</body>
</html>
I don't know if it is possible to default the value the file-input field shows but what you could do is just have a row above the input field showing the currently uploaded/chosen file (if there is any). So something like this:
<td>
<form class="" action="{{url_for('main.upload_file')}}" method="post" enctype="multipart/form-data">
<input type="hidden" name="id" value="{{row.id}}">
{% if row.name %}
<p>Currently chosen file: {{row.name}}</p>
<p>You can select a new file below</p>
{% endif %}
<input style="margin-bottom: 5px;" type="file" accept=".csv" name="csvfile" id="upload"> <br>
<input style="margin-bottom: 10px;" type="submit" name="" value="Submit"> <br>
</form>
<a href={{ url_for('main.files') }}>Go to Downloads Page</a>
<br>
</td>

Using '<path>' and GET forms on Flask

I have a configuration in my app that goes something like this:
#app.route("/path/<path:sub_path>", methods = ['GET'])
def path(sub_path):
print("Subpath is: " + str(sub_path))
return 1
And a form that looks something like:
<form role="form" class="" action="http://localhost:5000/path/<path:sub_path>" method="GET">
<input type="text" name="sub_path" id="sub_path" placeholder="Search 2..">
<input type = "submit" value = "submit" />
</form>
However, the print statement returns "Subpath is: <path:sub_path>".
How can I properly send the URL using the GET method?

Referencing an HTML button to Python Script

My objective in this program is to store information in a database. My problem is that I'm trying to link a button from my HTML page by using a Python script. My instructor told us that it must be written in Python. Any Libraries that support Python 2.7 would work for me.
from google.appengine.api import images
from google.appengine.ext import ndb
from models import Note
import webapp2
import jinja2
import os
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainHandler(webapp2.RequestHandler):
def get(self):
template = jinja_env.get_template('./main.html')
self.response.out.write(template.render())
class InfoHandler(webapp2.RequestHandler):
def get(self):
note = Note(img = images.Image(photo.usr_img))
class Note(ndb.Model):
def get(self):
usr_img = ndb.BlobProperty()
desc = ndb.StringProperty()
app = webapp2.WSGIApplication([
('/', MainHandler),
], debug=True)
<html>
<head lang = "en">
<meta charset = "UTF-8">
<title>Title</title>
</head>
<body>
<div class = "container">
<h1>If this is an emergency, upload a photo and provide a short description.</h1>
<div id = "upload" >
<label for = "img">Upload image:</label>
<input type = "file" name = "pic" accept = "image/*"/>
<label for = "desc">Description:</label>
<input type = "text" />
<input type = "submit" href = "{{ submit_data }}"/>
</div>
</div>
</body>
</html>
I'm a noob in Python and I'm taking on a tough problem for class. Any suggestions or solutions?

Python Flask render_template returns HTML script instead of redirecting to the HTML page

I have a Python script that uses Flask web framework to let users ask a question and depending on some certain questions, the application should ask back some questions to the user on a second webpage. The answers to the questions are evaluated based on the questions and displayed on the initial webpage.
model.py
### Importing Flask ###
from flask import Flask, render_template, request, session, redirect, url_for
### Initializing Flask ###
app = Flask(__name__)
#app.route('/')
def index():
return render_template('init.html')
#app.route('/handle_data', methods = ['POST', 'GET'])
def handle_data():
### User Inputs Question ###
userQuestion = request.form['userQuestion']
def model():
message = "Depends on User"
if message == "Depends on User":
return render_template('user_information.html', userQuestion = userQuestion)
else:
message = "Your answer is ABC."
return message
message = model()
return render_template('init.html', userQuestion = userQuestion, message = message)
#app.route('/user_information', methods = ['POST', 'GET'])
def user_information():
userLevel = request.form['userLevel']
userDOJ = request.form['userDOJ']
userType = request.form['userType']
message = "Answer for Eligibility."
return render_template('init.html', userLevel = userLevel, userDOJ = userDOJ, userType = userType, message = message)
if __name__ == '__main__':
app.run()
These are my two HTML files:
init.html (initial webpage)
<!DOCTYPE html>
<html>
<head>
<title>Human Resources</title>
<!-- for-mobile-apps -->
</head>
<body>
<div class="main">
<div class="w3_agile_main_grid">
<h2>Human Resource Portal</h2>
<br>
<p>Hi</p>
<form action="{{ url_for('handle_data') }}" method="post" class="agile_form">
<input type="text" name="userQuestion" placeholder="Ask your question..." required="">
<input type="submit" value="Submit">
</form>
<p>{{ message }}</p>
</div>
</div>
</body>
</html>
user_information.html (second webpage)
<!DOCTYPE html>
<html>
<head>
<title>Human Resources</title>
</head>
<body>
<div class="main">
<div class="w3_agile_main_grid">
<h2>Human Resource Portal</h2>
<form action="{{ url_for('user_information') }}" method="post" class="agile_form">
<!--<input type="text" name="userName" placeholder="Enter your name." required="">-->
<input type="text" name="userLevel" placeholder="What is your level?" required="">
<input type="text" name="userDOJ" placeholder="What is your date of joining?" required="">
<input type="text" name="userType" placeholder="Are you on sabbatical or specialist?" required="">
<input type="submit" value="Submit">
</form>
</div>
</div>
</body>
</html>
When I execute my script and enters a question, what I get is the HTML code for user_information.html as my answer which is not what I want.
Ouput after I click Submit:
https://ibb.co/cwhRpk
Expected output after I click Submit:
https://ibb.co/c7CFh5
https://ibb.co/dX9T25
I can get the desired output if I remove the model() construct but that will make my code inefficient because in my actual application I have to call model() multiple times with different parameters.
Can anyone please suggest me what approach should I take? I'm totally stuck in this part. Thanks, any help is appreciated!
Your nested model() function does not make any sense at all. It returns the result of render_template, which is a complete response including HTTP headers etc. If you try and insert that into another template, Jinja will be forced to try and convert it to a string, which gives the result you see.
This is not at all the way to compose templates. Jinja supports template inheritance; you should call render_template once only, using a child template that inherits from a common base.

Call multiple functions from a single route in flask

I have 2 functions in a single direction of page.
How to access both of them individually?
Now what's happening is, only 1st function is getting called.
The below program is a madeup prototype and my requirement builds on this logic.
from bottle import get,post,run,route,request
content1 = '''
<html>
<h1>Page 1 function </h1>
<form action='details' method='post'>
<input type = "text" name="uname">
<input type = "submit" >
</form>
</html>'''
content11 = '''
<html>
<h1>Page 2 function </h1>
<form action='details' method='post'>
<input type = "text" name="uname">
<input type = "submit" >
</form>
</html>'''
content2 = '''<html><h1>Hello %s </h1></html>'''
#get('/home')
def page1():
return content1
def page2():
return content11
#post('/details')
def page3():
u_name = str(request.forms.get('uname'))
return content2 %u_name
run(host='localhost', port=8080, debug=True)
The way you are asking the question implies you want to provide two separate web pages from the same address. REST doesn't work this way.
You need to provide a second route to access the code in page2()

Categories