So I am using Flask as micro framework and in one of my templates I am using the following Table:
<table id = "productentabel" width = "auto" class="table table-striped b-t b-b">
<thead>
<tr class = "header">
<th>Name</th>
<th>Url</th>
</thead>
{% for file in all_files['files'] %}
{% if file['mimeType'] == 'application/vnd.google-apps.document' %}
<TR>
<TD width="auto" >{{file['name']}}</TD>
<td><a class="btn btn-xs white" href = "https://docs.google.com/document/d/{{file['id']}}" target ="_blank">Go to file</a></td>
<td><form method=POST action="delete_file"><input type=submit name="delete" value ="{{file['id']}}" class="btn btn-xs white">Delete file</input>
</form></td>
</TR>
{% endif %}
{% endfor %}
</tr>
</table>
My question is about the following HTML code:
<form method=POST action="delete_file"><input type=submit name="delete" value ="{{file['id']}}" class="btn btn-xs white">Delete file</input>
</form>
As you can see I am trying to pass a value to my Python code when a click is made on the input. The value is passed to my Python code, but now the value is visible on the front end, so it looks like this:
1svpTERHaYd-wSpFBRRRjp1TOj0H-FH4_66H2W1OLY Delete file
But I want it to be like this:
Delete file
In Python I am doing the following to extract the value:
fileid = request.form.get('delete')
I also tried something like this:
<form method=POST action="delete_file"><input type=submit name="{{file['id']" class="btn btn-xs white">Delete file</input>
</form>
But I don't really know how I then can extract the name in my Python code, because I only need file['id'] to be passed and the value solution worked for me but that is not the ideal solution.
Instead of POST try the GET method, like this:
<td><form method="get" action="delete_file?file_name={{file['id']}}"><input type="submit" name="delete" value ="Delete file" class="btn btn-xs white"/></td>
If you want the POST method, you should send the file name via input with the hidden type.
<td><form method="post" action="delete_file"><input type="submit" name="delete" value ="Delete file" class="btn btn-xs white"/><input type="hidden" name="file_id" value="{{file['id']}}" /></td>
In this case you'll get the file id like this:
fileid = request.form.get('file_id')
BTW: most of your HTML isn't valid, you should really watch a tutorial about it.
Related
The submission button is not working properly. I'm getting the desired output after submitting the form. Kindly let me know where I'm going wrong. Find the attached .html and .py code below. Also, let me know what's the difference between using "button" tag and "input" tag as buttons in html?
main.py
mysql=MySQL(app)
#app.route("/",methods=["GET","POST"])
def insert():
cur=mysql.connection.cursor()
if request.form=='POST':
print(request.form["description"])
cur.execute("select * from test.task")
task=cur.fetchall()
cur.close()
return render_template("base.html",task=task)
if __name__=="__main__":
app.run(debug=True, port=8000)
base.html
<body>
<h3>Table</h3>
{% block body %}
<div>
<form action="/" method="POST">
<label for="description">Description</label>
<input type="text" name="description" id="description" placeholder="Description Input" required>
<button type="submit">Submit</button>
</form>
</div>
<br>
<div class="=Task">
<table>
<tr>
<th>S.No.</th>
<th>Description</th>
<th>Date and time</th>
<th>Action</th>
</tr>
{% for task in task %}
<tr>
<td>{{loop.index}}</td>
<td>{{task.1}}</td>
<td>{{task.2}}</td>
<td>Update Delete
</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock body %}
</body>
</html>
Try replacing this with:
if request.form == "POST":
with
if request.method == "POST":
I am trying to get data from a table from an HTML that I created, that table has data from a table from a sqlite database.
So, for each checkbox marked in that table, I need to get the data from that row.
However, I am only receiving data from the first line, even if I mark several lines.
I've tried using the getlist, and creating an array, but without success. Since I am still learning from Flask and etc., I already looked for examples but I also couldn't find a solution.
My HTML table:
HTML code:
<form method="POST">
<table id="example" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>Id_Game</th>
<th style="width: 800px;">Game</th>
<th style="width: 100x;">Critic Score</th>
<th style="width: 100px;"><input type="checkbox" id="all" onclick="checkAll(this)"></th>
</tr>
</thead>
<tbody>
{% for game in games.items %}
<tr>
<td name="ID_GAME" id="ID_GAME">{{ game.ID_GAME}}</td>
<input type="hidden" name="ID_GAME" value="{{ game.ID_GAME }}" />
<td name="NM_GAME"> {{ game.NM_GAME}} </td>
<input type="hidden" name="NM_GAME" value="{{ game.NM_GAME }}" />
<td name="NR_CRITICSCORE">{{ game.NR_CRITICSCORE}}</td>
<td>
<input type="checkbox" id="one_checkbox" name="one_checkbox">
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if current_user.is_authenticated %}
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
{% else %}
<div class="form-group">
<button type="submit" class="btn btn-primary" onclick="submitoff()">Submit</button>
</div>
{% endif %}
</form>
Python code:
#main.route('/games/<int:page_num>', methods=('GET', 'POST'))
def games(page_num):
games = V_GAMES.query.paginate(per_page=10, page=page_num, error_out=True)
if request.method =='POST':
if request.form.getlist('one_checkbox'):
ID_USER = current_user.id
ID_GAME = request.form.get('ID_GAME')
NM_GAME = request.form.get('NM_GAME')
IC_PLAYED = "YES"
SYSDATE = datetime.datetime.now()
# create new user with the form data. Hash the password so plaintext version isn't saved.
addprofile = USERGAMESPLAYED(ID_USER=ID_USER, ID_GAME=ID_GAME, NM_GAME=NM_GAME, IC_PLAYED=IC_PLAYED, DT_PLAYED=SYSDATE)
# add the new user to the database
db.session.add(addprofile)
db.session.commit()
flash('Games have been successfully added to your profile.')
if not request.form.get('one_checkbox'):
flash('You have to check at least one game to add to your profile!')
return render_template('games.html', games=games)
In this two lines of code
ID_GAME = request.form.get('ID_GAME')
NM_GAME = request.form.get('NM_GAME')
You are always getting the data from the first line since you are using get but not gelist.
The way I would do this is to first modify your checkbox
<td>
<input type="checkbox" id="one_checkbox" name="one_checkbox" value="{{ your_game_id }}">
</td>
So that you can get all the games that are checked by their id
print(request.form.getlist('one_checkbox'))
[checked_game_id_1, checked_game_id_2, ...]
Then, use a for loop to loop through the checked games, use their id to get ID_GAME and NM_GAME, and do your processing.
EDIT
To get NM_GAME by ID_GAME
for id in request.form.get('one_checkbox')
game = V_GAMES.query.filter_by(ID_GAME=id).first()
nm_game = game.NM_GAME
I create a table show book info from SQLite database and I'm trying to create an "Add New Book form" to make it add a new book into a table database. How can I add a book and then make it show into the table Book Info ?
<div class="container-fluid">
<!-- Add Book -->
<div class="add-book">
<h1>Add a Book</h1>
<form action="/add_book" method="POST" class="add_more_book">
{% csrf_token %}
<p>
<label for="title" id="title">Title:</label>
<input type="text" name="title" class="form-control" id="input-title" />
</p>
<p>
<label id="desc" for="desc">Description:</label>
<textarea class="form-control" name="description" id="input-desc" rows="3"></textarea>
</p>
<button type="submit" class="btn shadow btn-primary" id="addbtn">
Add
</button>
</form>
</div>
<!-- End of Add Book -->
<!-- Book info -->
<div class="book-info">
<form action="/" method="POST">
{% csrf_token %}
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{% for i in all_books_info %}
<tr>
<th scope="row">{{i.id}}</th>
<td>{{i.title}}</td>
<td>Views</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
</div>
Lets say you have an a table named Bio in your models.py file. Like so
class Bio(models.Model):
author = models.CharField(max_length= 20, null=True)
book = models.CharField(max_length= 20, null=True)
title = models.CharField(max_length=50)
desc = models.CharField(max_length=200)
Assuming you have imported you models at the top of you views.py file.
from .models import *
The * imports all the models from the models file.( There are reasons you may or may not want to import all the models in the future.)
In the views.py file
def processInfo(request):
print(request.POST["title"]
if len(str(request.POST["title"])) < 2:
print("Needs more the 2 characters to submit")
else:
print("Meets rule")
Bio.objects.create(title = request.POST["title"])
The print is there to see if anything is received. You always want to check first if you are not getting an empty string. I use len and other tools to check https://www.w3schools.com/python/ref_func_len.asp
There are a few ways on creating and getting data from the django models.
https://docs.djangoproject.com/en/3.0/topics/db/queries/
Finally for the function that renders "/" in the views.py file. Once you retrieve the data that you are looking for, return it with the request and html file.
I've been working on a really simple,maybe trivial, flask application that manages users' credentials, like a sysadmin page (change username, password, privileges, email).
Right now I've written the following code in HTML:
<div id="signup-box" class="signup-box" style=" background-color:rgb(149, 202, 202); width: 60%;">
<table class="table" style="background-color:#ffffff00;">
<thead >
<tr>
<th style="text-align:center; vertical-align:inherit;">Username</th>
<th style="text-align:center; vertical-align:inherit;">Role</th>
<th style="text-align:center; background-color:rgba(104, 159, 223, 0.384);">Control</th>
<tr>
</thead>
<tbody>
{% for i in range(0,lenUser) %}
<tr class="tr">
<td style="text-align:center; vertical-align:inherit;">{{ users[i] }}</td>
<td style="text-align:center; vertical-align:inherit;">{{ roles[i] }}</td>
<td style="text-align:center;">
<button form="edit_form" type="submit" value="Edit" class="button is-warning is-focused" style="margin-right: 45px;">Edit User</button>
<button form="delete_form" type="submit" value="Delete" class="button is-danger is-focused" style="margin-right: 45px;">Delete User</button>
<form id="edit_form" action="{{ url_for('edit_user', id=users.id) }}" method="POST">
<input type="hidden" name="_method" value="EDIT">
</form>
<form id="delete_form"action="{{ url_for('delete_user', id=users.id) }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
in Python:
#app.route("/delete_user/")
def delete_user():
if not session.get('logged_in'):
return redirect(url_for('login'))
con = sqlite3.connect('sqlite:///accounts.db')
cur = con.cursor()
cur.execute('DELETE FROM User WHERE id = "' + request.args.get('id')+ '"')
cur.commit()
con.close()
return flask.jsonify({'success':"True"})
And as a Python helper to fetch my users:
def fetch_users():
with session_scope() as s:
usrs = s.query(tabledef.User.username).order_by(tabledef.User.username).all()
tblUsrs = df.from_records(usrs)
return(tblUsrs)
Now, what it does is that it fetches my users as a dataframe and it outputs them row by row in my html table, which is what it was intended to do. But I also want to delete the specific user when I press the button "Delete" in the HTML page, right? Problem is that I can't seem to find a way to select the specific id of the user from the following lines:
<form id="delete_form"action="{{ url_for('delete_user', id=users.id) }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
</form>
How can I fix that? Because it is in a loop and every time the string I get is that of the first line
I am trying to create an app where a user can manage a database of "Lost property" items. To do so I have a main page where all the items are displayed and I have a button per row to be clicked when the item is returned to the owner.
That button is submitting a form that should contain the ID value of the element that has been clicked so I trying to get something like
<input id="id_id" name="id" type="hidden" value="{{lostitem.id}}">
But I don't know how to pass that value to my form ! Here is my template :
{% for lostitem in lostitems %}
<tr>
<td>{{lostitem.id}}</td>
<td>{{lostitem.description}}</td>
<td>
<form class="give-back-item-form" method="POST">
{% csrf_token %}
{{formGiveBackItem.as_p}}
<button type="submit" class="button btn btn-xs btn-success buttonItems">
<span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span>
</button>
<!-- TRYING TO ADD A HIDDEN INPUT WITH THE ID AS VALUE -->
</form>
</td>
</tr>
{% endfor %}
Here is my form from forms.py
class GiveBackItemForm(forms.ModelForm):
id = forms.CharField(widget=forms.HiddenInput())
class Meta:
model = ItemLost
fields = ('id',)
And here is where I'm trying to get my $_POST['id'] and to update my object (I couldn't test this part as I'm not getting any POST information at the moment) :
from .forms import GiveBackItemForm
"""Defining our views"""
def item_list(request):
formGiveBackItem = GiveBackItemForm()
"""Ordering objects by date of creation"""
lostitems = ItemLost.objects.filter(added_date__lte=timezone.now()).order_by('added_date')
if request.method == "POST":
"""Giving back an item"""
itemToGive = ItemLost.objects.get(pk=request.POST.get('id'))
itemToGive.giveBackItem
"""Returning our ordered objects to the view"""
"""Request = everything we receive from the user (in a form for example)"""
return render(request, 'lostitem/item_list.html', {'lostitems': lostitems, 'formGiveBackItem' : formGiveBackItem})
Thanks for any help or remark about the code ! I'm just getting started and it was really hard to find anything helpful about my problem
EDIT : I managed to make it work by still using the Django ModelForm and the view to handle my form
Here is my code in my view :
def item_list(request):
"""Ordering objects by date of creation"""
lostitems = ItemLost.objects.filter(added_date__lte=timezone.now()).order_by('added_date')
"""To get data from the form"""
give_back_item_form = GiveBackItemForm(request.POST or None)
# check if form is valid
if give_back_item_form.is_valid():
itemToGive = ItemLost.objects.get(pk=give_back_item_form.cleaned_data['id'])
itemToGive.returned_date=timezone.now()
itemToGive.save()
# your rest of the code here
"""Returning our ordered objects to the view"""
"""Request = everything we receive from the user (in a form for example)"""
return render(request, 'lostitem/item_list.html', {'lostitems': lostitems, 'give_back_item_form' : give_back_item_form})
And here is the code for my template !
<form class="give-back-item-form" method="POST">
{% csrf_token %}
<input type="hidden" name="id" value="{{ lostitem.id }}">
<button type="submit" class="button btn btn-xs btn-success buttonItems">
<span class="glyphicon glyphicon-share-alt" aria-hidden="true"> </span>
</button>
</form>
Thank you all for your answers it lead me to the right solution !
If all you want to do is post back the id of an associated ItemLost object so that you can invoke a method on it (e.g., giveBackItem()), there's no need to use a ModelForm at all. Just use a normal HTML <form>, and manually put the hidden field in it:
<form class="give-back-item-form" method="POST">
{% csrf_token %}
<button type="submit" value="Give Back">
<input type="hidden" name="id" value="{{lostitem.id}}">
</form>
So your complete template would become:
{% for lostitem in lostitems %}
<tr>
<td>{{lostitem.id}}</td>
<td>{{lostitem.description}}</td>
<td>
<form class="give-back-item-form" method="POST">
{% csrf_token %}
<button type="submit" class="button btn btn-xs btn-success buttonItems">
<span class="glyphicon glyphicon-share-alt" aria-hidden="true"></span>
</button>
<input type="hidden" name="id" value="{{lostitem.id}}">
</form>
</td>
</tr>
{% endfor %}