How to update a specific table of a webpage in flask? - flask

I am using flask 2.0 and there is a table on my webpage that shows the status of the transaction. Actually, the status is being updated by calling a MySQL DB hosted in my server. And the table is only updated with the latest data once the webpage is refreshed fully. Is there a way that I can call the MySQL DB and update just the table when I check refresh button next to the table?
The current code and extract is shown below:
Flask App:
cursor.execute('Select * from process WHERE email=%s ORDER BY timestamp DESC LIMIT 20', (email,))
transactions = cursor.fetchall()
return render_template('clientarea.html', transactions=transacions)
HTML:
<table class="table table-hover table-bordered table-sm" style="text-align:center">
<thead>
<tr>
<th scope="col" style="width: 25%">Date</th>
<th scope="col" style="width: 25%">Process Count</th>
<th scope="col" style="width: 25%">Completed Process</th>
<th scope="col" style="width: 25%">Failed Process</th>
</tr>
</thead>
{% for transaction in transactions %}
<tbody>
<tr>
<td>{{ transaction.get('date').strftime("%d %B, %Y") }}</td>
<td>{{ transaction.get('pcount') }}</td>
<td>{{ transaction.get('pcompleted') }}</td>
<td>{{ transaction.get('pfailed') }}</td>
</tr>
</tbody>
{% endfor %}
</table>
Is it possible to load the updated value without refreshing the page using flask?

use AJAX
Insert this code into head tag in html
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script>
$(function () {
$('#refreshBtn').on('click', function () {
$.ajax({
method: 'get',
url: 'http://localhost:5000/table-refresh',
dataType: 'json',
success : function(data){
$.each(data, function(val) {
$('#date_' + data[val][0]).html(data[val][1]);
$('#pcount_' + data[val][0]).html(data[val][2]);
$('#pcompleted_' + data[val][0]).html(data[val][3]);
$('#pfailed_' + data[val][0]).html(data[val][4]);
});
}
});
});
});
</script>
Grant id in table rows, add new refresh button
<td id="date_{{ transaction.id }}">{{ transaction.get('date').strftime("%d %B, %Y") }}</td>
<td id="pcount_{{ transaction.id }}">{{ transaction.get('pcount') }}</td>
<td id="pcompleted_{{ transaction.id }}">{{ transaction.get('pcompleted') }}</td>
<td id="pfailed_{{ transaction.id }}">{{ transaction.get('pfailed') }}</td>
<input type="button" id="refreshBtn" value="refresh" />
Finally, create new router for refreshing table
#app.route('/table-refresh', methods=['GET'])
def table_refresh():
# [[id, date, pcount, pcompleted, pfailed], ...]
arr = [[1, '2021-08-23', 1, 1, 1], [2, '2021-08-24', 1, 1, 1]]
return jsonify(arr)

Related

Flask-security delete user return an error

I'm trying to add a delete button on my users admin page in a flask app.
But I already have this error when I click on button :
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'builtins.str' is not mapped
This is my adminusers.html file :
{% extends 'base.html' %}
{% block main %}
<main>
<table class="table table-striped users">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Roles</th>
<th scope="col" class="text-center">Delete</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<th scope="row">{{ user.id }}</th>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>
{% for role in user.roles %}
{{role.name}};
{% endfor %}
</td>
<td style="text-align: center;"></i></td>
</tr>
{% endfor %}
</tbody>
</table>
</main>
{% endblock main %}
And my app.py file :
#app.route('/adminusers')
def list_users():
users= User.query.all()
return render_template('adminusers.html', users=users)
#app.route('/delete_user/<user>')
def delete_user(user):
user_datastore.delete_user(user=user)
db.session.commit()
return redirect(url_for('adminusers'))
I'm trying to use the 'email' or 'name' but it already return an error
Thanks #pjcunningham, like that it works :
#app.route('/delete_user/<id>')
def delete_user(id):
user = user_datastore.get_user(id)
user_datastore.delete_user(user)
db.session.commit()
return redirect(url_for('adminusers'))

How to update database value in django on a button click

I have a template that contains one search button (this is for filtering the details based on option choose in the select) and a Next button (this is to move to next tab).
When the template loads for then i will search for projects from the select list and the result will be displayed in a table - which is working for me.
After the result is displayed in the table, i will select a row (through radio button) from that table and click on Next button to move to next tab. Here when i click the Next button i want to update some values in the django database but not able to achieve this. Can some one help me?
My View:
def form(request):
projects = CreateProjects.objects.filter(Status=True)
if request.method == 'POST':
selectproject = request.POST.get('selectproject')
searchprojlist = ListProjDetails.objects.filter(Project=selectproject)
return render(request,'form.html',{'projects':projects,'lists': searchprojlist})
elif request.POST.get('tab1btn','') == 'nxttab':
selval = ListProjDetails.objects.get(id=1)
selval.Selected = True
selval.LockedUser = request.user
selval.save()
else:
lists = ListProjDetails.objects.all()
return render(request,'form.html',{'projects':projects})
First If POST is working correctly, trouble is with the 2nd IF (2nd button). I have swapped the 2nd IF to be called fresh after the else statement but not working either.
I have passed id=1 for testing purpose only
enter image description here
I have added the image for better understanding, basically when the template loads select project from the list and Search and then choose one from the output and press next that moves to next tab by updating values like select to True and Locked User to current user.
My view as explained before.
My Javascript:
$(function(){
$('#nexttab').click(function(e){
e.preventDefault();
if(document.getElementById('selectradio').checked){
$('#tabs a[href="#tab2"]').tab('show');
}
});
})
Template:
<form method="POST">
{% csrf_token %}
<div class="row ml-auto">
<select class="custom-select mb-4 ml-2" name="selectproject" style="width: 30em;">
<option selected>Choose...</option>
{% for projects in projects %}
<option>{{ projects.ProjName}}</option>
{% endfor %}
</select>
<div class="ml-4">
<button type="submit" class="btn btn-primary" value="Search">Search</button>
</div>
</div>
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col" class="text-center">S.No.</th>
<th scope="col" class="text-center">Project Name</th>
<th scope="col" class="text-center">Doc</th>
<th scope="col" class="text-center">Target Date</th>
<th scope="col" class="text-center">Docnum</th>
<th scope="col" class="text-center">Type</th>
<th scope="col" class="text-center">Select</th>
<th scope="col" class="text-center">Locked by User</th>
<th scope="col" class="text-center">Status</th>
</tr>
</thead>
<tbody>
{% for lists in lists %}
<tr>
<th scope="row" class="text-center">{{ lists.id }}</th>
<td class="text-center">{{ lists.Project }}</td>
<td class="text-center">{{ lists.doc }}</td>
<td class="text-center">{{ lists.TargetDate }}</td>
<td class="text-center">{{ lists.docnum }}</td>
<td class="text-center">{{ lists.type }}</td>
<td class="text-center"><input class="form-check-input" type="radio"
name="select1" id="selectradio" value="option1"></td>
<td class="text-center">{{ lists.LockedUser }}</td>
<td class="text-center">
{% if lists.DStatus == "Available" %}
<label class="badge badge-success">
{% else %}
<label class="badge badge-warning">
{% endif %}
{{ lists.DStatus }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-right mr-5">
<button type="submit" class="btn btn-primary" id="nexttab" name="tab1btn"
value="nxttab">Next</button>
</div>
</form>
I am just trying to re-factor your code, you should be able to pickup then.
from django.shortcuts import render, redirect
from django.urls import reverse
def form(request):
projects = CreateProjects.objects.filter(Status=True)
if request.method == 'POST':
if request.POST.get('tab1btn','') == 'nxttab':
selval = ListProjDetails.objects.get(id=1)
selval.Selected = True
selval.LockedUser = request.user
selval.save()
return redirect(reverse('name-of-the-view')) # redirect to form.html
selectproject = request.POST.get('selectproject')
searchprojlist = ListProjDetails.objects.filter(Project=selectproject)
return render(request,'form.html',{'projects':projects,'lists': searchprojlist})
else:
lists = ListProjDetails.objects.all()
return render(request,'form.html',{'projects':projects})

Edit a cell in the table save to the django model

I have a table of employees. I am loading data using $http and using ng-repeat to print it on the webpage. I want to edit each row content.
HTML:
tbody ng-repeat="list in data" >
<tr ng-hide="edit" ng-click="edit=true">
{% verbatim %}
<td> {{$index + 1}}</td>
<td>{{ list.associate_nbr }}</td>
<td>{{ list.per }}%</td>
<td>{{ list.count }}</td>
<td>{{ list.sample_per }}%</td>
<td>{{ list.sample}}</td>
<td><input type="text" value="{{ list.focused
}}"></td>
<td><input type="text" value="{{
list.random_field }}"></td>
</tr>
{% endverbatim %}
MAIN.JS
(function(){
'use strict';
angular.module('sampling.demo',[])
.controller('SamplingController', ['$scope','$http',SamplingController]);
function SamplingController($scope,$http)
{
$scope.data = [];
$http.get('/sample/').then(function(response){
$scope.data = response.data;
});
}
}());
I want to edit the last two fields when user clicks on it.

Update data in database based on order id in Django

I am new in Django.
I want to update the value in the database based on the order id. Therefore, every order id has different updates. But, i only can update the last item that i add to the order. And every previous orders that i have, will directly follow the update from the last item.
models.py
class OrderItem(models.Model):
Table_No = models.IntegerField(blank=False)
FoodId = models.TextField()
Item = models.TextField()
Qty = models.DecimalField(max_digits=5, decimal_places=0)
Price = models.DecimalField(max_digits=10, decimal_places=2)
TotalPrice = models.TextField()
Note = models.TextField(max_length=100, null=True)
OrderId = models.TextField(max_length=5, null=True)
FoodStatus = (
('1', 'Has been ordered'),
('2', 'cooked'),
('3', 'ready to be served'),
('4', 'done'),
)
food_status = models.CharField(max_length=50, choices=FoodStatus)
views.py
def kitchen_view(request):
chef_view = OrderItem.objects.all()
if request.method == "POST":
order_id = request.POST.get("OrderId")
status = OrderItem.objects.filter(OrderId=request.POST.get("OrderId"))
status.status1 = OrderItem.objects.update(food_status=request.POST.get("food_status"))
return render(request, 'restaurants/kitchen_page.html', {'chef_view': chef_view})
kitchen_page.html
<form action="#" method="post">
<style>
table, th, td {
border: 1px solid black;
}
</style>
{% csrf_token %}
{% for order in chef_view %}
<table width="800">
<tr>
<th width="800">Table Number</th>
<th width="800">Item</th>
<th width="800">Quantity</th>
<th width="800">Price</th>
<th width="800">Note</th>
<th width="800">Order Id</th>
<th width="800">Status</th>
</tr>
<tr>
<td width="800">{{ order.Table_No }}</td>
<td width="800">{{ order.Item }}</td>
<td width="800">{{ order.Qty }}</td>
<td width="800">{{ order.Price }}</td>
<td width="800">{{ order.Note }}</td>
<td width="800">{{ order.OrderId }}</td>
<td width="800">{{ order.food_status }}
<input type="text" name="food_status">
</tr>
</table>
{% endfor %}
<br><a href='' button onclick="myFunction()"><input type="submit" value="Change Status"></button>
</form>
The result should be able to update the food_status based on the order_id. Therefore, every order_id may have different food_status and show it to the template.
Anyone can help me to solve this problem? I really need the help to solve this issue. Really appreciate.
Ok so real problem is that your form is incorrect - you are not sending OrderId to view. Here's quickfix to it:
kitchen_page.html:
<style>
table, th, td {
border: 1px solid black;
}
</style>
<form action="#" method="post">
<table width="800">
<tr>
<th width="800">Table Number</th>
<th width="800">Item</th>
<th width="800">Quantity</th>
<th width="800">Price</th>
<th width="800">Note</th>
<th width="800">Order Id</th>
<th width="800">Status</th>
</tr>
{% csrf_token %}
{% for order in chef_view %}
<tr>
<td width="800">{{ order.Table_No }}</td>
<td width="800">{{ order.Item }}</td>
<td width="800">{{ order.Qty }}</td>
<td width="800">{{ order.Price }}</td>
<td width="800">{{ order.Note }}</td>
<td width="800">{{ order.OrderId }}</td>
<td width="800">{{ order.food_status }}
<input type="text" name="food_status" value="{{ order.food_status }}">
</tr>
<input type="hidden" name="OrderId" value="{{ order.OrderId }}">
{% endfor %}
</table>
<br><button type="submit" value="Change Status">Change Status</button>
</form>
views.py:
def kitchen_view(request):
if request.method == "POST":
order_ids = request.POST.getlist("OrderId")
food_statuses = request.POST.getlist("food_status")
for i in range(len(order_ids)):
OrderItem.objects.filter(OrderId=order_ids[i]).update(food_status=food_statuses[i])
chef_view = OrderItem.objects.all()
return render(request, 'restaurants/kitchen_page.html', {'chef_view': chef_view})
Previously stored filtered objects are not being updated as you have
status = OrderItem.objects.filter(OrderId=request.POST.get("OrderId"))
but when you are updating them, you should be updating the already filtered objects like
status = status.update(food_status=request.POST.get("food_status"))
Hope this helps.
You can update multiple objects at once including the filter in a single line as:
status = OrderItem.objects.filter(OrderId=request.POST.get("OrderId")).update(food_status=request.POST.get("food_status"))
The problem in your code:
status.status1 = OrderItem.objects.update(food_status=request.POST.get("food_status"))
was that you were not using the filter, instead you tried updating the status1 field(Can't see a status1 field in your model) using status.status1.

django trying to put a table in a view

in my views.py:
def show(request):
query_results=Emails.objects.all()
#from py_utils import open_py_shell;open_py_shell.open_py_shell()
context = { 'query_result' : query_results }
return render(request, 'show.html', context)
in show.html:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
<tbody>
{% for item in query_result %}
<tr>
<td>Ohad</td>
<td>{{ item.email }}</td>
<td>{{ item.baseurl }}</td>
</tr>
{% endfor %}
</tbody>
</table>
an email object has email field and baseurl field but it seems that i cannot load it,
i checked and in query_result i have a list of Emails object just cannot put it in the table, any help?