django: View to delete html table row not taking effects in Database - python

I have a page that displays rows from a db table. I added a button to each row that is designed to delete the row upon its click as well as redirect toward a deleted confirmation page. Everything seems to work, unless that nothing gets deleted in the database table.
Here is what my views.py look like:
def ProductsView(request):
queryset = Products.objects.all()
products_list = list(queryset)
request.session['context'] = products_list
#table = ProductsTable(queryset)
#context = {'table':table}
return render(request, 'inventory.html', {'products_list':products_list})
def DeleteProduct(request, Id):
Products.objects.filter(ProductId=Id).delete()
return render(request,'delete_confirmation.html')
and here is what the html page look like, including the code for the delete button
<table class="table text-center table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th scope="col">ID</th>
<th scope="col">NAME</th>
<th scope="col">CATEGORY</th>
<th scope="col">TAG NUMBER</th>
<th scope="col">STOCK ON HAND</th>
<th scope="col">DELETE</th>
</tr>
</thead>
<tbody style="background-color: white">
{% for Products in products_list %}
<tr>
<td>{{ Products.ProductId }}</td>
<td>{{ Products.ProductName }}</td>
<td>{{ Products.ProductCategory }}</td>
<td>{{ Products.ProductTagNumber }}</td>
<td>{{ Products.StockOnHand }}</td>
<td>
<a class="btn btn-primary" href="{% url 'delete_confirmation' Id=Products.ProductId %}" style="color: white">Delete</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
here is what urls.py looks like:
path('inventory.html', ProductsView, name="inventory"),
path('delete_confirmation/<int:Id>', DeleteProduct, name="delete_confirmation"),
and when I print Id in console inside of the ``DeleteProduct``` view, it ouputs the correct Id value
I can't find out what I am doing wrong, I have been at it all day and need a pair of fresh eyes to look at it! Does anyone has a clue on what is wrong here?

Related

Generating new HTML rows for each Document from firestore in python Django

I have a collection of documents in a Firestore database. I want to create a web form to display all the documents and their fields. I started by streaming all the documents using:
docs = db.collection(u'users').stream()
and then appending all the docs IDs to a list and pass it to the HTML file as follows
def index(request):
myIDs =[]
db = firestore.Client()
docs = db.collection(u'users').stream()
for doc in docs:
myIDs.append(f'{doc.id}')
return render(request, 'index.html', {
"weight":"abc",
"firstRow":myIDs[0],
"secondRow":myIDs[1],
"thirdRow":myIDs[2],
"fourthRow":myIDs[3],
"fifthRow":myIDs[4],
"sixthRow":myIDs[5],
"seventhRow":myIDs[6],
})
After that, I created a very basic HTML code just to display the document IDs as follows:
<html>
<body>
<table border="1" cellpadding = "5" cellspacing="5">
<tr>
<td>{{ firstRow }}</td>
<tr>
<td>{{ secondRow }}</td>
</tr>
<tr>
<td>{{ thirdRow }}</td>
</tr>
<tr>
<td>{{ fourthRow }}</td>
</tr>
<tr>
<td>{{ fifthRow }}</td>
</tr>
<tr>
<td>{{ sixthRow }}</td>
</tr>
<tr>
<td>{{ seventhRow }}</td>
</tr>
</tr>
</table>
</body>
</html>
Till this point I am just doing very basic stuff. But I am new to Django and Python for the Web, so my question is: how can I make it so that the HTML rows become adaptive based on the number of documents?
For example, if I have 20 documents, I want to make it so that it will generate the 20 rows and pass each of the document IDs to one row, and so on.
This is fairly simple in Django
You can pass the list MyIDs as a context variable and let your template do the heavy lifting
return render(request, 'index.html', {
"weight":"abc",
"myIDs": myIDs
})
Then in your template
<table border="1" cellpadding = "5" cellspacing="5">
{% for id in myIDs %}
<tr>
<td>{{ id }}</td>
</tr>
{% endfor %}
</table>
(I suspect you can make this even simpler by passing docs as a context variable, which would let you do
{% for doc in docs %}
<tr>
<td>{{ doc.id }}</td>
<td>{{ doc.title }}</td>
</tr>
{% endfor %}
</table>
but I'm not 100% familiar with the output of stream() )

Issue with passing python function to jinja

I am working on a Flask web app and I am at a point where I want the admin of the site to be able to approve/deny users. The issue I am facing is that I am trying to call Python functions in html/jinja template. Here is a look. demo
In the user_approval.html file
``
<table id="user-approval" class="table table-striped table-bordered">
<thead>
<tr>
<th>Full Name:</th>
<th>Address:</th>
<th>DOB:</th>
<th>Email:</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{% for user in users.items %}
<tr>
<td>{{ user.a_name }}</td>
<td>{{ user.a_address }}</td>
<td>{{ user.a_dob }}</td>
<td>{{ user.a_email }}</td>
<td><button id="approve-user-btn" onclick="{{ user_approve }}">approve</button></td>
<td><button id="deny-user-btn" onclick="{{ user_deny }}">deny</button></td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th>Full Name:</th>
<th>Address:</th>
<th>DOB:</th>
<th>Email:</th>
<th></th>
<th></th>
</tr>
</tfoot>
</table>
``
I would need to pass the user_id as an argument. I tried to do something like this
<button id="approve-user-btn" onclick="{{ user_approve(user.id) }}">approve</button>
Which calls the functions before admin clicks.
This is not going to work, the onclick event can be used to run Javascript, but in this case you should rather create a route in Jinja to run Pyton code. You need to add a <form> in your HTML too, and in your form you set the target accordingly (using the function url_for). Change the button like this too, so it behaves like a submit element:
<button id="approve-user-btn" type="submit"...
or
<input id="approve-user-btn" type="submit"...
And probably add a hidden field for the user ID as well. This value will be included in the form (POST) request.

Django template loop through API results to display in table

so I have some data being returned via API which I am passing into my template I am having an issue though in displaying the data as currently it is showing each char per row, I am trying to make it so in the table I have the coin name in a row with the value in the next col and so on.
Data being returned-
{"error":[],"result":{"ZGBP":"30622.0790","DASH":"0.5104491200","ADA":"2473.80445621","ZUSD":"67787.8285","KSM":"24.7142610000","CHZ":"13773.0349000000","XXLM":"6926.27220000","KNC":"0.0000000000","MATIC":"1838.9295772000","ZRX":"0.0000000000","BAL":"0.0000000000","XXDG":"17006.92601155","LINK":"144.2407000000","USDT":"60000.00000000","TRX":"923.80015900","COMP":"0.0000034600","ENJ":"257.6815000000","DOT":"0.0000000000","XLTC":"11.4923900000","SC":"0.0000000200","XZEC":"0.0000073100","SOL":"1133.3543869800","SUSHI":"172.4585500000","XXRP":"0.00000000","XETH":"14.5877343640","AAVE":"83.6218990800","ATOM":"151.26763831","XXBT":"0.0000012880","ALGO":"32063.69514500","OCEAN":"652.6077000000"}}
My template-
<table class="table table-hover table-bordered">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Amount</th>
</tr>
</thead>
<tbody>
{% for v in api_reply %}
<tr>
<td>{{ v }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Probably you get the string object instead of json, but if it is a json...
In template use this:
<tbody>
{% for k,v in api_reply['result'].items() %}
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
{% endfor %}
</tbody>```

Issue rendering with nested tables in Django

I'm trying to loop two tables within each other. I have a list of tasks that each have a list of materials. I'd like to next the tables within each other. However, the code below doesn't render the second task into columns. So, when it loops it seems as if the table structure is destroyed. I'm using Django/Python.
<div class="table-responsive">
<table id="taskTable" class="table">
{% for task in projecttype.projecttask_set.all %}
<h5>Task - {{ task.name }}</h5>
<thead class="alert-success">
<tr>
<th>Quantity</th>
<th>Units</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ total_units_required }}</td>
<td>{{ task.base_unit_label }}</td>
<td>{{ task.base_unit_cost }}</td>
</tr>
</tbody>
<table id="materialTable" class="table">
<thead>
<tr class="alert-info">
<th>Material</th>
<th>Cost per Task Unit</th>
<th>Material Cost</th>
<th>Total Cost</th>
</tr>
</thead>
{% for material in task.materials.all %}
<tbody>
<tr>
<td>{{ material.name }}</td>
<td>{{ material_quantity_per_task_base_unit }}</td>
<td>{{ total_material_quantity }}</td>
<td>{{ total_material_cost }}</td>
</tr>
</tbody>
{% endfor %}
</table>
{% endfor %}
</table>
</div>
I encountered the same issue. The nested table has to be inside a table cell
e.g.:
<table>
<tr>
<td>
<table>
...
</table>
</td>
</tr>
</table>

Python: How can I implement this in a DRY way using Jinja2?

I have lots of code like this in my template:
<h2>Owners of old cars</h2>
<table id="hor-minimalist-b" summary="Old Cars">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Address</th>
</tr>
</thead>
<tbody>
{% for result in old_cars %}
<tr>
<td>{{result.name}}</td>
<td>{{result.age}}</td>
<td>{{result.address}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h2>Owners of Ford cars</h2>
<table id="hor-minimalist-b" summary="Old Cars">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Address</th>
</tr>
</thead>
<tbody>
{% for result in ford_cars %}
<tr>
<td>{{result.name}}</td>
<td>{{result.age}}</td>
<td>{{result.address}}</td>
</tr>
{% endfor %}
</tbody>
</table>
There will be lots more tables created like those above. As you can see there is lots of duplicate code. Is there anyway to do this so I don't repeat as much code each time a create a table? Thanks.
UPDATE
I'm thinking about creating a new object, called table, and adding a result and the corresponding h2 title to it. I can then create a list of these table objects, called tables, which I can pass to the template. The template can then iterate over them.
Surely what you want, ideally, is:
{% for car in cars %}
<h2>Owners of {{ car.manufacturer }}</h2>
<table id="hor-minimalist-b" summary="Old Cars">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Address</th>
</tr>
</thead>
<tbody>
{% for model in car.models %}
<tr>
<td>{{model.name}}</td>
<td>{{model.age}}</td>
<td>{{model.address}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endfor %}
I'm not sure what ORM you're using, but in Django that wouldn't be too hard to construct; after all, all you pass in is a list of objects with subobjects and fields.
Again, I can only talk for a django perspective (construct from your own ORM), but you can either deliberately construct the dictionary with explicit requests for each type of manufacturer, or rather have a model for "sales" and a model for "manufacturer" and construct a many-to-many relationship between the two. Your query roughly looks like this, in django python:
result = []
manufacturers = Manufacturer.objects.all() # get all manuf
for m in manufacturer:
mf = dict()
mf["manufacturer"] = m.name
mf["models"] = m.model_set.all() # get all linked models
result.append(mf)
# pass result to template as cars
Does that make sense?
Use template for the header and footer of the table
<table id="hor-minimalist-b" summary="Old Cars">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Age</th>
<th scope="col">Address</th>
</tr>
</thead>
<tbody>
Put this in a file named "table_header.html" and include it in your template.
The same for the footer!

Categories

Resources