Check if the user's input is valid - python

Users are entering their address and age. When the find button is hit, it will display the inputs. However, for the case where input is not valid, I would like to add an error message.
How do I check if the input is not valid and gives an error message? I want my error message to be on the same page as where values are input. The code does not work correctly.
<div class = "Information">
<h2>Your Infomation</h2>
<form action="" method=post>
if (error){
<p id="error"><strong></strong>{{error}}
}
<div id = "address">
<label>address</label>
<input type=text name=address value="{{request.form.address}}">
</div>
<div id = "age">
<label>age</label>
<input type=text name=age value="{{request.form.age}}">
</div>
<div class = "Input">
<a href="/results">
<button type = "button" class = "btn btn-primary" value="find" >Find!</button>
</a>
</div>
</form>
</div>
#app.route('/results',methods=['GET','POST'])
def result():
error = None;
if request.method == 'POST':
if request.form['age'] != '14':
error='You did not enter proper values'
return render_template('template.html',error=error)

You need to use proper Jinja syntax to render templates:
{% if error %}<p id="error">{{ error }}</p>{% endif %}
Beyond that, the button you've added to your form doesn't actually submit the form, as you've given it the "button" type rather than the "submit" type and have wrapped it in an anchor for some reason. Replace the contents of <div class="Input"> with:
<button type="submit" class="btn btn-primary" value="find">Find!</button>

Related

How can I ask user to upload image to an html page, insert this image to an sqlite3 table using flask, and then display this image using jinja?

so far this is what I came up with
#html ask user to input information including an image
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="name" placeholder="name" type="text">
</div>
<div class="form-group">
<input class="form-control" name="subject" placeholder="subject" type="text">
</div>
<div class="form-group">
<input class="form-control" name="experience" placeholder="experience" type="text">
</div>
<div class="form-group">
<input class="form-control" name="phone" placeholder="puone-number" type="number">
</div>
<div class="form-group">
<input type="file" name="pic" id="pic">
</div>
<button class="btn btn-primary" type="submit">Register</button>
</form>
flask
#app.route("/register", methods=["GET", "POST"])
def register():
"""Show teacher registering menu"""
if request.method == "GET":
return render_template("register.html")
else:
# get the user input
name = request.form.get("name")
sub = request.form.get("subject")
exp = request.form.get("experience")
phone = request.form.get("phone")
f = request.files['pic']
pic = f.save(secure_filename(f.filename))
if not name or not sub or not exp or not phone:
return "404"
# insert in the database
sql = "INSERT INTO teachers (name, sub, exp, phone, pic) VALUES (?, ?, ?, ?, ?)"
db.execute(sql, name, sub, exp, phone, pic)
# inform the user for the success of the process
return render_template("success.html")
showing the results on html
<div>
{% for i in query %}
<div class="media bg-primary text-white">
<img class="align-self-end mr-3" src={{ i['pic'] }} alt="Generic placeholder image">
<div class="media-body">
<h5 class="mt-0">Mr. {{ i['name'] }}</h5>
<ul class="list-group list-group-flush text-dark">
<li class="list-group-item">subject: {{ i['sub'] }},</li>
<li class="list-group-item">experience: {{ i['exp'] }},</li>
<li class="list-group-item">Contact number: {{ i['phone'] }}</li>
</ul>
</div>
</div>
<br>
{% endfor %}
</div>
but right now every time I try it I find the value of the image column in my sql table to be NULL.
How can I fix that
pic = f.save(secure_filename(f.filename))
The save method returns None, so here pic will be None.
I think you intended to write its filename to the database, so perhaps change this to:
pic = secure_filename(f.filename)
f.save(pic)
Now pic is the filename on your server, so you just need to reconstruct this wherever the file is viewed.
Of course be aware that this uses the filename of the file which was uploaded by the user. You may wish to avoid this, incase of duplicates or just for cleanliness. See this other answer I wrote regarding that.
EDIT: Regarding your template.
When it comes to loading the picture in the template, let's assume the filename came through as image.jpg, and you use your exisiting code:
<img src={{ i['pic'] }}>
You could view the source of the rendered page, and see:
<img src=image.jpg>
Two problems with this:
that attribute should have quotes (<img src="image.jpg">)
that's trying to load the file from whichever path is rendered in the browser, so if the URL was http://example.com/subdir/ it's looking for the image at http://example.com/subdir/image.jpg. This can also be verified in the Network tab of your browsers dev tools.
The solution, build the URL with flask's url_for function:
<img src="{{ url_for('static', filename=i['pic']) }}">
This, of course, assumes that you've saved the file to the static directory on your server. You may wish to ensure this in the python code:
import os
# ...
pic = secure_filename(f.filename)
f.save(os.path.join('static', pic))

How to add the feature to display video formats with the resolution of user's choice to download

The below code is in views.py .I want to take a variable from the user instead of the '360p' after user pastes the video link. Is there a way to show how to get the resolution from the user.I have to take input from the user.
The full code looks something like the below webpage
https://www.hexascholars.com/code-snippet/youtube-video-download-using-django-and-python/
def get_download(request):
if request.method == 'GET':
if(request.GET.get('url')):
url = request.GET['url']
try:
yt = YouTube(url)
title = yt.title
stream = yt.streams.filter(res='360p').first()
path = download_path()
stream.download(path)
message = "Download Complete!"
video = Video()```
If you want to do it the "plain vanilla" way, i.e. without using django Forms you can just add a grup of radio buttons or a select to the form in your html, e.g.
<form method="GET" action="/your/url/">
<div class="form-group">
<label>Enter Youtube URL</label>
<input type="url" class="form-control" required="required" name="link">
</div>
<div class="form-group">
<label>Resolution</label>
<fieldset>
<input type="radio" name="res" id="res1" value="360p">
<label for="res1">360p</label>
<input type="radio" name="res" id="res2" value="720p">
<label for="res1">720p</label>
</fieldset>
</div>
<button type="submit" class="save btn btn-success">Download</button>
</form>
In your view you can fetch the parameter the same way you are getting the url:
res = request.GET.get('res')
and then use "res" instead of your hard-coded string.

400 Bad Request (Flask + html)

I keep getting a 400 Bad Request when I try to run my Flask project.
I have to do a project using Flask and HTML, and it was supposed to be a group project, so members would have to learn different parts of it to then gather everything. Sadly, my 'group' didn't do anything at all
Here's my code:
Flask
app = Flask(__name__, static_url_path="")
#app.route('/', methods=['POST','GET' ]) #1 - Login e criar conta
def PagInicio():
button = request.form["button"]
if request.method == 'POST':
if button == "login":
return render_template("Princ.html")
elif button =="criar":
return render_template("Criar.html")
else:
return render_template("Inicio.html")
return render_template("Inicio.html")
HTML:
<div class="col_12">
</div>
<!-- Tab 3 - Perfil -->
<div id="tabr3" class="tab-content">
<div class="grid">
<div class="col_2"></div>
<div class="col_8">
<form class="vertical" method="POST" action="/">
<fieldset>
<div class="grid">
<div class="col_6">
<label for="usuario">Usuário</label>
<input id="usuario" name="usuario" type="text" />
</div>
<div class="col_6">
<label for="senha">Senha</label>
<input id="senha" name="senha" type="password" />
</div>
<div class="col_12 center">
<button class="medium" value="login"</i> Login</button>
</div>
<div class="col_12 center">
<button class="medium" value="criar"</i> Criar</button>
</div>
</form>
</div>
<div class="col_2"></div>
</div>
</div>
</div>
<div class="col_1"></div>
</div>
You are trying to access the request.form dictionary, always:
button = request.form["button"]
This throws a 400 response error if there is no such value in the form. This is always the case when you have a GET request, request.form is only populated when there is POST data in a valid format.
Only try to access the button when you already confirmed you have a POST request:
def PagInicio():
if request.method == 'POST':
button = request.form["button"]
if button == "login":
return render_template("Princ.html")
elif button =="criar":
return render_template("Criar.html")
else:
return render_template("Inicio.html")
return render_template("Inicio.html")
Next, you don't actually have any form element named button. You have button form elements but none have a name. Give all your buttons the same name attribute, varying the value attribute:
<div class="col_12 center">
<button class="medium" name="button" value="login"> Login</button>
</div>
<div class="col_12 center">
<button class="medium" name="button" value="criar"> Criar</button>
</div>
Note that you malformed the <button tags too.

Passing values from one html page to another via Flask (Python)

My web app currently has 3 pages. I obtained a user input on the first page, which I passed to my view.py, and calculated some variables I needed for my 2nd page. I want to pass the variables that exist in my 2nd page to the third page, but don't know how to go about it. Any suggestions on how to modify the html for the 2nd page to achieve this?
So far, I'm solving this problem by making my variables global in view.py. This seems to work but doesn't seem to be a viable long-term solution.
Thanks!
existing variables: thePrediction, theData
The html for the 2nd page:
<div class = "caption-full">
<h3>Currently, I have a {{thePercentage}} chance of getting adopted.</h3>
{% if thePrediction[1] + thePrediction[2] >0%}
<form action="/third_page" method="GET">
<button class="btn btn-large btn-info" >Go to third page</button>
</form>
{% endif %}
</div>
I think I figured it out:
<div class = "caption-full">
<h3>Currently, I have a {{thePercentage}} chance of getting adopted.</h3>
{% if thePrediction[1] + thePrediction[2] >0%}
<form action="/third_page" method="GET">
<input type="hidden" name="alignment" value="{{thePassedValue}}" />
<button class="btn btn-large btn-info" >Go to third page</button>
</form>
{% endif %}
</div>

Page redirect to next page

I am using a map api in my app.For selecting marker, button named "Add marker" and "Refresh map" for refresh map.I am facing the here.
After saving the data,the save button will redirect to next page.in my case,both "Add marker","Refresh map" both are doing the save buttons job and if i press "Add marker" instead of showing marker,page gets redirect to next page.this is happening after using the </form>.see my template here,
<form method="POST" action="/member/where/" >
{% csrf_token %}
<td colspan="2" class="incident-type" style="padding-left:25px">
{% for location in locationList%}
{% if location.parent_location_id == None %}
<h1>{{location.title}}</h1>
{% endif %}
{% endfor %}
<p>
<span class="map_buttons" >{% include "buttons/refreshmap.html" %}</span> <span class="map_buttons" style="margin-left:20px;">{% include "buttons/addmarker.html" %} </span>
</p>
<p id=ir-nextbtn>{% include "buttons/next.html" %}</a></form></p>
refreshmarker.html
<button type="submit" title="Refresh map" class="map_buttons button_style">Refresh map</button>
addmarker.html
<button type="submit" title="Add marker" class="map_buttons button_style">Add marker</button>
Need clarification about this issue.
The problem is because both the buttons are of type submit, when you click either of the buttons, the form gets submitted. as a result, the page gets redirected oto action of the form i.e. /member/where/
try this:-
keep the refresh as it is,
<button type="submit" title="Refresh map" class="map_buttons button_style">Refresh map</button>
and add
<button onClick=somefuntion(this)' title="Add marker" class="map_buttons button_style">Add marker</button>
and let some function do the needfull
<script>
function somefuntion(button){
// your code
document.forms[0].submit() // this will submit your form
}
</script>

Categories