Pass information from html form to python flask - python

I am new to flask and web applications, trying to create a web application that takes the name and the sport for each user and store it in sqlite DB, now Iam trying to remove users from the DB by taking the registrant id from the html to flask.
flask:
#app.route("/deregister")
def deregister():
value_from_html = ?????
db.excute("DELETE * FROM registrant WHERE id = ?", value_from_html)
html:
{% extends "layout.html" %}
{% block body %}
<h1>Registrant name</h1>
<tbody>
{% for registrant in registrants %}
<tr>
<td>{{ registrant.name }}</td>
<td>{{ registrant.sport }}</td>
<td>
<form action="/deregister" method="post">
<input name="id" type="hidden" value="{{ registrant.id }}"> !-- trying to pass registrant.id to flask --!
<input type="submit" value="Deregister">
</form>
</td>
</tr>
{% endfor %}
</tbody>
{% endblock %}
python code is not complete yet.

You can recieve the form data in the following way.
#app.route("/deregister", methods=['POST'])
#login_required
def deregister():
try:
if request.method == 'POST':
if request.files:
uploaded_file = request.files['filename']
data = uploaded_file.stream.read()
In order to send a variable to flask, you dont need to use forms, you can easily do that in the following way,
#app.route("/deregister/<string:id>", methods=['POST'])
#login_required
def deregister(id):
try:
variable = id
print(variable)
In html, keep this,
{% extends "layout.html" %}
{% block body %}
<h1>Registrant name</h1>
<tbody>
{% for registrant in registrants %}
<tr>
<td>{{ registrant.name }}</td>
<td>{{ registrant.sport }}</td>
<td>
<a href='/deregister/{{ registration.id }}'>Send Id</a>
</td>
</tr>
{% endfor %}
</tbody>
{% endblock %}

After trying to solve it my self finaly Ive found a way to do that:
1)Add button in my html to remove from DB:
I hope that this will help any one as it did for me.

Related

Populating an HTML table from Django views.py

I have an HTML table that I want to be populated from views.py. Here is my code:
index.html
{% for item in pizza %}
<tr id="{{ item.name }}">
<td>{{ item.status }}</td>
<td>{{ item.name }}</td>
</tr>
{% endfor %}
views.py
def pizza(request):
pizza_data = [{'name': 'Pepperoni Pizza', 'status': 'Ready'}]
return render(request, "index.html", {'pizza': pizza_data})
The table doesn't get populated and I don't see any error code. Is it the format in pizza_data? I removed the other {% for %} loop because Lucas is right that the other loop is useless.
I think I should say that index.html is inside a folder named templates. Not sure if this will affect because I declared the STATIC_DIR into this folder.
The reason why pizza_data is hardcoded is because that is a JSON file that I need to figure out how to insert but for now I want to see if the {% for %} loop can populate but it is not.
Try this code it's working
views.py
def pizza(request):
pizza_data = [{'name': 'Pepperoni Pizza', 'status': 'Ready'}]
return render(request, "index.html", {'pizza_data': pizza_data})
HTML Table
<table class="table ">
<thead>
<th>Item Name</th>
<th>Status</th>
</thead>
<tbody>
{% for item in pizza_data %}
<tr id="{{ item.name }}">
<td>{{ item.name }}</td>
<td>{{ item.status }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Output in Browser
Use .items to loop through the dictionary:
{% for obj in pizza %}
<tr id="{{ obj.name }}">
{% for key, value in obj.items %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
You have to rename your variable i think. And the second loop is useless, your put a dictionary in context, so you just need to access by key of each element:
def pizza(request):
pizza_data = [{'name': 'Pepperoni Pizza', 'status': 'Ready'}]
return render(request, "index.html", {'pizzas': pizza_data})
{% for pizza in pizzas %}
<tr id="{{pizza.name}}">
<td>{{pizza.status}}</td>
<td>{{pizza.name}}</td>
</tr>
{% endfor %}
Your code at least shows result, However If you get template does not exist error It has another solution.

Search result does not show up

I am trying to create a database search engine using sqlite3, Python Flask and HTML in Visual Studio Code. I want to fetch title and attribution where title contains user's search input.
app.py :
#app.route("/explore", methods=["GET", "POST"])
#login_required
def explore():
if request.method == "GET":
return render_template("explore.html")
else:
search = request.form.get("search")
conn = sqlite3.connect("project.db")
cur = conn.cursor()
query = cur.execute("SELECT title, attribution FROM objects WHERE title LIKE ?", [search])
cols = ["object_title", "attribution"]
conn.commit()
results= pd.DataFrame(query.fetchall(), columns=cols)
conn.close()
return render_template('searchresult.html', results=results)
explore.html (search engine):
{% extends "layout.html" %}
{% block title %}
Explore Artworks
{% endblock %}
{% block main %}
<form action="/explore" method="POST">
<div class="mb-3">
<input autocomplete="on" autofocus class="form-control mx-auto w-auto" name="search" placeholder="Artist or Artwork" type="text">
</div>
<button class="btn btn-outline-primary" type="submit">Search</button>
</form>
{% endblock %}
searchresult.html :
{% extends "layout.html" %}
{% block title %}
Search Result
{% endblock %}
{% block main %}
<table>
<thead>
<td> Title </td>
<td> Attribution </td>
</thead>
{% for result in results %}
<tr>
<td> {{ result["object_title"] }}</td>
<td> {{ result["attribution"] }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
However, search result page only shows an empty table:
searchresult.html with empty table

Django: select all data from a row in a html table and use them in a view

I am new to both django and web development.
The task is to run a script when pressin a button using the data contained in the specific row of an html table.
So if i clik on the second button "Run script" it uses all the data in that row (8888, 2020/06/21 06:00) in a separate script to performe some task.
Currently my html file looks like this:
There are 2 sections one for uplading the information that goes in the table one the table which displays them
<h1>Approach Path KML Generator</h1>
<h2>Generate the KML file here:</h2> <form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button onclick="location.href='{% url 'approach_path_receptorsKML:Proejct Creator' %}'">Upload</button> </form>
<h2>Projects Available:</h2>
<table class="table">
<thead>
<tr>
<th>Project ID</th>
<th>Date KML</th>
<th>Time KML</th>
<th>Date-Time Uploaded</th>
<th>Run The Conversion</th>
<th>KML File</th>
</tr>
</thead>
<tbody>
{% for project in latest_project_list %}
<tr>
<td>{{ project.project_ID }}</td>
<td>{{ project.date_kml }}</td>
<td>{{ project.time_kml }}</td>
<td>{{ project.upload_time }}</td>
<td>
<button method="post" value="collect data" name="{{ project.project_ID }}|{{ project.date_kml }}|{{ project.time_kml }}|{{ project.upload_time }}">Run script</button>
</td>
<td>
Download KML File
</td>
</tr>
{% endfor %}
</tbody> </table>
And this is the view I have created:
def ProjectCreator(request):
form = DocumentForm()
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid:
form.save()
elif 'collect data' in request.POST.values():
values = [key for key in request.POST.keys()]
print(values)
else:form = DocumentForm()
I have tried to use this guide (How do I pass table data from a template over to Django on a button/submit click?) however, I have been insuccesfull.
If anyone can spot the mistake I have made and give me some explanation I would be grateful.
Thanks
It doesn't work because you have incorrect HTML layout. Button itself doesn't do anything - in order to send POST request, it should be in <form> tag. Try following:
{% for project in latest_project_list %}
<tr>
<td>{{ project.project_ID }}</td>
<td>{{ project.date_kml }}</td>
<td>{{ project.time_kml }}</td>
<td>{{ project.upload_time }}</td>
<td>
<form method="post">
{% csrf_token %}
<button value="collect data"
name="{{ project.project_ID }}|{{ project.date_kml }}|{{ project.time_kml }}|{{ project.upload_time }}">
Run script
</button>
</form>
</td>
<td>
Download KML File
</td>
</tr>
{% endfor %}
This will work, but I doubt this is great way of achieving this. You can just send project.pk with POST request and fetch project in view. This way you can be sure user will not send incorrect/malicious data with request. It is especially important since your code will run script based on data.

Python, Django: get data from select-fields inside a table

inside my app I have a table that contains a select-field in each row. After pressing the submit-button I would like to receive all the selected values inside a list (or something else that's usable):
template:
<form method="POST">
{% csrf_token %}
<table name="table-example">
<thead>
...
</thead>
<tbody>
{% for item in list_example %}
<tr>
<td>...</td>
<td>...</td>
<td>
<select name="select-example">
{% for item in list_selections %}
<option name="option-example" value="{{ item }}">{{ item }}</option>
{% endfor %}
</select>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit">Update</button>
</form>
When trying to receive data from I only get one field!
if request.method == "POST":
data = request.POST.get('option-example', None)
What am I doing wrong or what am I missing here? Or is this even possible?
Thanks for all your help and have a great day!

How to pass arguments to included html in Flask web application

I am developing a blog application in python with flask. In the view function form is passed as argument to render_template which calls 'index.html'. form works in index.html as expected. But there is a {% include '' %} tag which places 'post.htm'. Now I want to use same form repeatedly in 'post.html'. How to do that? Will the passed form to index.html available to included 'post.html' also? And if so how to identify which button is pressed in the rendered page because both forms are same? My index.html file:
{% extends "base.html" %}
{% block content %}
<h1>Hi, {{ g.user.nickname }}!</h1>
<form action="" method="post" name="post">
{{ form.hidden_tag() }}
<table>
..........
..........
<tr>
<td><input type="submit" value="Post!"></td>
</tr>
</table>
</form>
{% for post in posts.items %}
<div class="{{ post.id }}">
<div>
{% include 'post.html' %}
</div>
</div>
{% endfor %}
{% endblock %}
And my post.html as:
<table>
..........
..........
<tr valign="top">
<td>{{ post.body }}</td>
</tr>
<tr>
<form action="" method="post" name="post">
{{ form.hidden_tag() }}
<table>
.........
.........
<td><input type="submit" value="Post!"></td>
</table>
</form>
</table>
Is it possible to use same form on both html files. As there will be several form fields in the rendered web page, how to identify which button is pressed?
index.html is rendered with code:
return render_template('index.html',
title='Home',
form=form,
posts=posts)
To distinguish the different forms, you need some unique key, e.g. a hidden input-tag, which contains an ID:
<input type="hidden" name="post_id" value="{{post.id}}">
For the index-Form you can use as generic ID the value "new".

Categories