Checked rows are not being deleted from HTML table/ Database (Django) - python

I created an html table in a django template
<form action="/delete_team/" method="POST" >
{% csrf_token %}
<input type="submit" name = "delete" class="btn btn-danger float-right" value="Delete">
<table>
<thead>
<tr>
<th><input type="checkbox" class="checkAll" name="checkAll"></th>
<th>Team ID</th>
<th>Male</th>
<th>Female</th>
<th>Officer</th>
<th>Deadline</th>
</tr>
</thead>
<tbody>
{% for team in teams %}
<tr>
<td><input type="checkbox" name="checked" class="case"></td>
<td>{{ team.team_id}}</td>
<td>{{ team.male }}</td>
<td>{{ team.female }}</td>
<td>{{ team.officer }}</td>
<td>{{ team.date }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
here is the code that i wrote in my views.py:
def delete_team(request):
if request.method == "POST":
pkm = request.POST.getlist("checked")
selected_objects = mtch_tbl.objects.filter(team_id__in=pkm)
selected_objects.delete()
return HttpResponseRedirect("/main/")
now when i check a row and click delete nothing happens...i only get returned to my page again with the same data. Kindly point out my mistake, i can't figure out how to write the views
Here are my urls.py
from django.urls import path
from teamplanner import views
urlpatterns = [
...
path("delete_team/",views.delete_team),
]
Is it possible for the jQuery code to be interfering?

Your views have many codes that to me aren't necessary, if you're planning on deleting a team, it's just Normal that you've FIRST registered a team. So here's what you should do..
def delete_team(request,delete_id):
delete = mtch_tbl.objects.get(id=delete_id)
#to make it more interesting, you should add a view to your models (i,'ll display the model below)
delete.view=True
delete.delete()
return HttpResponseRedirect("/main/")
Add this to your models
Class modelname (models.Model):
view=models.BooleanField(default=False)
In your URLs here's what you should do:
urlpatterns = [
path("delete_team/(?<delete_id>\d+)/$",views.delete_team),
]''''
I hope this helps

I think you're storing it in a variable. Try this:
def delete_team(request):
if request.method == "POST":
pkm = request.POST.getlist("check")
mtch_tbl.objects.filter(team_id__in=pkm).delete()
return HttpResponseRedirect("/main/")

I figured out the answer after reading this S.O solution, it's not related to checkboxes but the idea is pretty much the same. All I did was edit my checkbox input tag a little and added values to it:
<tbody>
{% for team in teams %}
<tr>
<td><input type="checkbox" name="checked" class="case" value="{{ team.team_id }}"></td>
<td>{{ team.team_id}}</td>
<td>{{ team.male }}</td>
<td>{{ team.female }}</td>
<td>{{ team.officer }}</td>
<td>{{ team.date }}</td>
</tr>
{% endfor %}
</tbody>
that's all there was to it, no need to change the views or the url path.
Still I really appreciate the help, Thank You!

Related

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.

How do I pass a Flask table cell value to python function?

I have this table in Flask:
<tbody>
{% for record in records %}
<tr>
<td onclick=search_results()>{{ record.id }}</td>
<td>{{ record.contractor }}</td>
<td>{{ record.category }}</td>
<td><A HREF='tel:{{ record.phone }}'>{{ record.phone }}</A></td>
</tr>
{% endfor %}
</tbody>
And this function:
#app.route('/detail/<id>')
def search_results(id):
records = db.session.query(Feedback).filter(Feedback.id == id)
print('search')
for record in records:
print(record)
return render_template('pageDetail.html', records=records)
I have researched similar questions but struggling still to understand how I can pass the id number of the selected cell to the search_results function.
Thank you in advance!
You need to hit the endpoint from the html and not the function call, try doing this,
<tbody>
{% for record in records %}
<tr>
<td href='/detail/{{ record.id }}'>{{ record.id }}</td>
<td>{{ record.contractor }}</td>
<td>{{ record.category }}</td>
<td><A HREF='tel:{{ record.phone }}'>{{ record.phone }}</A></td>
</tr>
{% endfor %}
</tbody>
Your flask view is fine.
No Method has been specified for flask?
If not used then why not simply use a python function.
refer this example:
#app.route('/classify', methods=['GET','POST'])
# these requests trigger the getresponse function where data can be retrieved
def getresponse():
if request.method == 'GET':
return(render_template('main.html'))
if request.method == 'POST':
extracted_title = request.form['string']
try:
#app.route('/detail/<id>', methods=['GET'])
def search_results(id):
records = db.session.query(Feedback).filter(Feedback.id == id)
print('search')
for record in records:
print(record)
return render_template('pageDetail.html', records=records)

Django: autonumbering in HTML

Im currently trying to figure out how to autonumber my tables in my html template.
I can't seem to use the id in the database as it is not autoincrementing as it it is user dependant what they see, so the user would see not a correct ordering. Instead of seeing the table numbering go 1. 2. 3. it is 4. 8. 9. for example.
Originally i have tried this, which gave me the wrong outcome as described above:
template.html
{% for item in x%}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.a}}</td>
<td>{{ item.b}}</td>
<td>{{ item.c}}</td>
</tr>
I have tried something with a while loop:
template.html
{% for item in x %}
{% while z<= item %}
{% z=z+1 %}
<tr>
<td>{{ z }}</td>
<td>{{ item.a}}</td>
<td>{{ item.b}}</td>
<td>{{ item.c }}</td>
</tr>
{% endwhile %}
{% endfor %}
For your reference the model that these templates refer to:
models.py
from django.db import models
from django.conf import settings
class x(models.Model):
creation_date = models.DateTimeField(auto_now = True)
a = models.CharField(max_length=50)
b = models.CharField(max_length=50)
c = models.CharField(max_length=50)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
Thanks in advance for your help!
You can use forloop.counter to count the iterations of a loop. Try this:
{% for item in x %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ item.a}}</td>
<td>{{ item.b}}</td>
<td>{{ item.c}}</td>
</tr>
{% endfor %}
Reference: for template tag - Django Docs

Take URL Parameters from a Button in Django

I am trying to get url parameters like this:
<tbody>
{% for object in objects %}
<tr>
<td>{{ object.id }}</td>
<td>{{ object.user }}</td>
<td>{{ object.url }}</td>
<td>{{ object.minimum }}</td>
<td>{{ object.maximum }}</td>
<td>{{ object.requests }}</td>
<td>{{ object.stay }}</td>
<td class="text-Centre">
Run
</td>
</tr>
{% endfor %}
</tbody>
If I put my URL like this, it works since the view exists in view.py:
{% url 'trafficapp:generate_traffic' %}
Now, I am trying to take URL parameters with it, but I am unable to make how can I pass data from this button, and what should I put in my URL pattern for this. Kindly help, I am new to Django and still figuring out how it works.
you can add parameters after {% url %}
Run

Flask Form Only Passing First Item

I am building a cart using Flask for learning purposes. I chose to use SQLite with peewee(ORM) and WTForms. I have it set to display the items from the db with a description and image. I have a form that asks for the quantity then it should add the item and its quantity to the side bar.
The Issue
When You enter a quantity and hit 'add' all the quantity fields will fill with that number and it will post the name of the first item from the database to the sidebar with that quantity.
app.py
#app.route('/cart', methods=['GET', 'POST'])
#login_required
def cart():
form = forms.PartsSelectForm()
if request.method == 'POST':
l_name = Parts.get(Parts.id).part_name
models.List.create(l_part_name=l_name,
l_part_qty=form.quantity.data)
parts = Parts.select()
list = List.select()
return render_template('cart.html', parts=parts, list=list, form=form)
forms.py
class PartsSelectForm(Form):
quantity = IntegerField()
cart.html
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Image</th>
<th>Quantity</th>
<th>Action</th>
</tr>
</thead>
{% for part in parts %}
<tr>
<td>{{ part.part_name }}</td>
<td>{{ part.part_desc }}</td>
<td style="width: 200px; height:200px;"><img src="/static/img/{{ part.part_img }}" style="max-height:100%; max-width:100%"></td>
<form method="POST" action="">
<td>{{ form.quantity }}</td>
<td><button type="submit" id="submit" class="btn btn-success">Add</button></td>
</form>
</tr>
{% endfor %}
</table>
You loop over your parts, but you always use form.quantity, which will be the same on every iteration idependently from which "part" you're currently looping over.

Categories