How to update database value in django on a button click - django

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})

Related

Django Edit Or Delete Selected Rows In A Table - ListView

I have a table with checkboxes and I would like to be able to delete or edit a specific field value for all the selected rows in the table.
Here's an example table that would be awesome to recreate but I have not found examples anywhere how this may work in the view and template. https://examples.bootstrap-table.com/#
My current view, which is working with a table. Where can I start to make the leap from a basic table to an interactive one like in the example above?
Views.py
class EntryList(LoginRequiredMixin, ListView):
context_object_name = 'entry_list'
paginate_by = 100
# paginate_by = 5
#ordering = ['-pk']
model = Entry
template_name = "portfolios/entry_list.html"
def get_queryset(self):
return Entry.objects.filter(created_by=self.request.user).order_by('-pk')
def post(self, request, *args, **kwargs):
ids = self.request.POST.get('ids', "")
# ids if string like "1,2,3,4"
ids = ids.split(",")
try:
# Check ids are valid numbers
ids = map(int, ids)
except ValueError as e:
return JsonResponse(status=400)
# delete items
self.model.objects.filter(id__in=ids).delete()
return JsonResponse({"status": "ok"}, status=204)
entry_list.html
{% extends "dashboard/base.html" %}
{% load i18n %}
{% block content %}
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h2 class="text-gray-800">{% block title %}{% trans "Imported Entries" %}{% endblock %}</h2>
<a role="button" class="btn btn-success" href="{% url 'import' %}"><i
class="fas fa-plus-circle"></i> Import New Entires</a>
</div>
<!-- Content Row -->
<div class="row">
<div class="col-md-12">
<div class="card shadow mb-4">
<div class="card-body">
<div id="dataTable_wrapper" class="dataTables_wrapper dt-bootstrap4">
<div class="row">
</div>
<div class="row">
<div class="col-sm-12">
<table class="table-responsive-xl table table-hover table-striped table-bordered dataTable" id="dataTable" width="100%"
cellspacing="0" role="grid" aria-describedby="dataTable_info">
<thead>
<tr role="row">
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">ID
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Date
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Trade
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Type
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Symbol
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Amount
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Price
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Fee
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Reg Fee
</th>
<th class="sorting" tabindex="0" aria-controls="dataTable" rowspan="1"
colspan="1" aria-label="" style="">Ref
</th>
</tr>
</thead>
<tbody>
{% for entry in object_list %}
<tr role="row">
<td class="text-center">
<div class="custom-control-lg custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input form-control-lg" data-id="{{ entry.pk}}" id="check{{ entry.pk }}">
<label class="custom-control-label" for="check{{ entry.pk }}"></label>
</div>
</td>
<td>{{ entry.pk }}</td>
<td>{{ entry.date | date:"M d, Y h:i:s A"}}</td>
<td>{{ entry.trade.id }}</td>
<td>{{ entry.entry_type }}</td>
<td>{{ entry.symbol }}</td>
<td>{{ entry.amount }}</td>
<td>{{ entry.price }}</td>
<td>{{ entry.fee }}</td>
<td>{{ entry.reg_fee }}</td>
<td>{{ entry.transaction_id }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!--Pagination-->
<div class="row">
<div class="col-12 ">
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
It depends on how you've implemented your frontend, but assuming you have standard django templates, then I would suggest taking a look at datatables. There's quite a lot to it, but it is very stable and has a decent feature set, and the documentation is good. You can style it how you want using bootstrap.
Also, you link to Bootstrap Table - that should be the same principle. Read through the docs to understand how it works, and you will have to use Django template tags to render the data in the table.
Note that the table is implemented using HTML / Jquery, so it is not directly related to Django. All you need to do is to iterate over the django objects in your template (example)
EDIT
How to delete a selected row?
Suppose you could select N rows, and then click a button to delete all of these rows.
This could work as follows:
Add a handler to the delete button:
identify the selected rows
send an Ajax request to delete the rows
handle the success response to remove the deleted rows from the table
// SIMPLIFIED CODE SAMPLE
$("#delete-btn").click(function () {
var selectedRows = table.rows({"selected": true});
var dataObj = {
// parse selectedRows to get object ids
}
$.ajax({
url: '/api/delete-rows/',
type: 'post',
data: dataObj,
success: function (data, status, xhr) {
// remove the selected rows from the view
table.rows({"selected": true}).deselect().remove().draw();
}
})
}
How to select rows and quickly change a field for all of the selected rows?
The same principle here. Once rows are selected, have a handler which identifies the selected rows, then you can use the datatables api to update given fields (docs).

Delete multiple rows in django

I am trying to delete severals rows at the same time in django.
How can I simply change the state of the booleanfield 'to_delete', just by clicking on the checkbox?
I am using datatables. The way how I am doing it is to create a boolean to_delete in my model, when the checkbox is selected, I am calling the function delete_multiple_company in my view. However, this doesn`t work. Any idea, what I am doing wrong please. Many Thanks,
I`ve created my view:
views.py
def delete_multiple_company(request, company_id):
company = get_object_or_404(Company, pk=company_id)
company = Company.objects.get(pk=company_id)
company.objects.filter(to_delete=True).delete()
return HttpResponseRedirect(reverse("company:index_company"))
urls.py
url(r'^(?P<company_id>[0-9]+)/delete_multiple_company/$', views.delete_multiple_company, name='delete_multiple_company'),
models.py
class Company(models.Model):
to_delete = models.BooleanField(default=False)
index.html
<span class="fa fa-plus"></span>Delete Companies
<table id="dtBasicExample" class="table table-striped table-hover">
<thead>
<tr>
<th>Select</th>
<th>#</th>
<th>Checked ?</th>
</tr>
</thead>
<tbody>
{% for company in companys.all %}
<tr>
<td id="{{ company.id }}"><input type="checkbox" class="companyCheckbox" name="checkedbox" id="{{ company.id }}" value="{{ company.id }}"></td>
<td>{{ company.id }}</td>
<td>{{ company.to_delete }}</td>
</tr>
{% endfor %}
</tbody>
</table>
I experienced a similar issue as you, what I did was put in a form.
index.py
<form method="POST" class="post-form">{% csrf_token %}
<button type="submit" class="save btn btn-default">Delete</button>
<span class="fa fa-plus"></span>Delete Companies</a>
<table id="dtBasicExample" class="table table-striped table-hover">
<thead>
<tr>
<th>Select</th>
<th>#</th>
<th>Checked ?</th>
</tr>
</thead>
<tbody>
{% for company in companys.all %}
<tr>
<td id="{{ company.id }}"><input type="checkbox" class="companyCheckbox" name="checkedbox" id="{{ company.id }}" value="{{ company.id }}"></td>
<td>{{ company.id }}</td>
<td>{{ company.to_delete }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit" class="save btn btn-default">Delete</button>
</form>
Clicking on the button then triggered the POST method in my view.
views.py
def index(request):
if request.method == 'POST':
print('I made it here')
# Put your code here, note you will return a dict, so some trial and error should be expected

How to persist data found in tables within a django template, in postgresql

I am scraping several sites and I show the data obtained in 6 tables within a django template.
My intention is to persist the data of the tables in postgresql, but I can not realize how to perform that task.
In principle I am trying to save the data from the second table.
For this I have created the models that I show below, as well as a view that is called: registroDivisaArgentina ().
The template is called quotes.html and within it, there are 6 tables.
I have tried to work with a class called: RegisterArgentineValues () within a forms.py file
models.py
class DivisasArgentina(models.Model):
class Meta:
ordering = ['CodigoDA']
CodigoDA = models.CharField(max_length=50, primary_key = True)
Texto_para_Reporte = models.CharField(max_length=70)
def __str__(self):
return '{}'.format(self.Texto_para_Reporte)
class ValoresDivisasArgentina(models.Model):
class Meta:
ordering = ['Dia']
DivisasArgentina = models.ForeignKey(DivisasArgentina, on_delete=models.PROTECT)
Dia = models.DateField(default=date.today)
Hora = models.DateTimeField(default=timezone.now)
Compra = models.FloatField()
Venta = models.FloatField()
Variacion_dia_anterior = models.FloatField()
ClaveComparacion = models.CharField(max_length=1)
def __str__(self):
return '{} - {} - {}'.format(self.DivisasArgentina, self.Dia, self.ClaveComparacion)
cotizaciones.html
{% extends 'base.html' %}
{% block contenido %}
<form method="POST" class="post-form">{% csrf_token %}
<div class="container">
<table class="table table-striped table-bordered" id="tab1">
<thead>
<tr>
<th>Divisas en el Mundo</th>
<th>Valor</th>
</tr>
</thead>
<tbody>
<tr>
{%for element in cotiz_mun%}
<tr>
{% for key,value in element.items %}
<td> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</tr>
</tbody>
</table>
</div>
<div class="container">
<table class="table table-striped table-bordered" id="tab2">
<thead>
<tr>
<th>Divisas en Argentina</th>
<th>Compra</th>
<th>Venta</th>
</tr>
</thead>
<tbody>
<tr>
{%for element in cotiz_arg%}
<tr>
{% for key,value in element.items %}
<td>{{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</tr>
</tbody>
<thead>
{{ form.as_table }}
</table>
</div>
<div class="container">
<table class="table table-striped table-bordered" id="tab3">
<thead>
<tr>
<th>Dolar Banco Nacion Argentina (Divisas)</th>
<th>Compra</th>
<th>Venta</th>
</tr>
</thead>
<tbody>
<tr>
{%for element in cotiz_exp%}
<tr>
{% for key,value in element.items %}
<td>{{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</tr>
</tbody>
</table>
<table class="table table-striped table-bordered" id="tab4">
<thead>
<tr>
<th colspan="4">Dolar Futuro en Argentina</th>
</tr>
<tr>
<th>Mes 1</th>
<th>Mes 2</th>
<th>Mes 3</th>
<th>Mes 4</th>
</tr>
</thead>
<tbody>
<tr>
{%for element in cotiz_dol%}
<td>
{{ element.Valores}}
</td>
{% endfor %}
</tr>
</tbody>
</table>
<table class="table table-striped table-bordered" id="tab5">
<thead>
<tr>
<th colspan="3">Indicadores Varios - Tasa Libor</th>
</tr>
<tr>
<th>Libor a 1 Mes</th>
<th>Libor a 2 Mes</th>
<th>Libor a 3 Mes</th>
</tr>
</thead>
<tbody>
<tr>
{%for element in cotiz_lib%}
<td>
{{ element.Valores }}
</td>
{% endfor %}
</tr>
</tbody>
</table>
<table class="table table-striped table-bordered" id="tab6">
<thead>
<tr>
<th>Indicadores Varios - Indice Merval y Oro</th>
<th>Valores</th>
</tr>
</thead>
<tbody>
<tr>
{%for element in cotiz_ind%}
<tr>
{% for key,value in element.items %}
<td> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</tr>
</tr>
</tbody>
</table>
</div>
<div class="container" id="saveData">
<br></br>
<button type="submit" class="btn btn-primary pull-right">Guardar Datos</button>
</div>
</form>
{% endblock %}
views.py
def mostrar_cotizaciones(request):
cotiz_arg = json.loads(j_cotizaciones_argentina)
cotiz_mun = json.loads(j_cotizaciones_mundiales)
cotiz_exp = json.loads(j_cotizacion_export)
cotiz_dol = json.loads(j_dolar_futuro)
cotiz_ind = json.loads(j_indicadores)
cotiz_lib = json.loads(j_libor)
context = {'cotiz_mun': cotiz_mun,
'cotiz_arg': cotiz_arg,
'cotiz_exp': cotiz_exp,
'cotiz_dol': cotiz_dol,
'cotiz_ind': cotiz_ind,
'cotiz_lib': cotiz_lib,
}
return render(request, 'cotizaciones.html', context)
def registrarDivisaArgentina(request):
if request.method == 'POST':
formulario = RegistrarValoresDivisasArgentinas(request.POST)
if formulario.is_valid():
formulario.save()
return HttpResponseRedirect('/listadoValores')
else:
formulario = RegistrarValoresDivisasArgentinas()
formulario.setup('Registrar', css_class="btn btn-success")
return render(request, 'cotizaciones.html', {'formulario':formulario})
forms.py
from django import fla
from django.forms import ModelForm
from django import forms
from fla.models import *
class RegistrarValoresDivisasArgentinas(forms.ModelForm):
class Meta:
model = ValoresDivisasArgentina
fields= [Compra, Venta]
I have done some tests, but none has given a favorable result. Someone can tell me how to process the data (in the views and forms) that are in the tables, to be able to store them in my postgres tables ?
I do this kind of task very often, and I've found out that the combination of ScraPy with scrapy-djangoitem is a very good combo to use here.
Good luck!

How to display 2 queryset list Frond end?(Django ListView get_queryset)

I got 2 queryset list expired_item and queryset in Django ListView, but I don't know when item is expired(queryset is empty), how to display another list expired_item on frond end, no matter what I changed in abc.html, expired_item won't dispaly, I pasted my code as below:
class ABCListView(ListView):
model = ABC
ordering = ('name', 'skill_course')
context_object_name = 'abcs'
template_name = ''
def get_queryset(self, **kwargs):
# Omitted
......
......
# Omitted
expired_item = list(ABC.objects.filter(pk__in=aa).exclude(pk__in=z))
queryset = Permit.objects.filter(pk__in=z)
return queryset
And my html file of abc.html as below:
{% extends 'base.html' %}
{% block content %}
<nav aria-label="breadcrumb">
</nav>
<h2 class="mb-3">My Items list</h2>
<div class="card">
<table class="table mb-0">
<thead>
<tr>
<th>Name</th>
<th>Department</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
{% for a in abcs %}
<tr>
<td class="align-middle">{{ a.name }}</td>
<td class="align-middle">{{ a.department.get_html_badge }}</td>
<td class="align-middle badge badge-pill badge-danger">{{ a.status }}</td>
</tr>
{% empty %}
{% endfor %}
</tbody>
</table>
</div>
<h2 class="mb-3">My Expired Items list</h2>
<div class="card">
<table class="table mb-0">
<thead>
<tr>
<th>Name</th>
<th>Department</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
{% for b in expired_item %}
<tr>
<td class="align-middle">{{ b.name }}</td>
<td class="align-middle">{{ b.department.get_html_badge }}</td>
<td class="align-middle badge badge-pill badge-danger">{{ a.status }}</td>
</tr>
{% empty %}
{% endfor %}
</tbody>
</table>
</div>
<div class="card-footer">
{% endblock %}
Thanks so much for any advice!
I would suggest use a normal django view. This Generic ListView is just created for the use of one list. Just pass both querysets in your context and render your template with that.
You could also use get_context_data() but this would be more or less hacky and not the qay I would recommend.

Adding rows breaks datatable in Django

I have a datatable in Django that functions fine when hardcoded, but when I add my Django template tags it breaks. The inspect on the page says: Uncaught TypeError: Cannot set property '_DT_CellIndex' of undefined in jquery.datatables.min.js
This only happens when I have more than one user in the table, or try to add a column in the table with django. Since I will be using multiple datatables in my project, I need to figure out what I'm doing wrong. The datatable JS code I'm using comes from a template, and I'm not sure if the error is in the template code or in my Django template code. So please excuse the long code blocks.
employees.html (django template):
<div class="card-body collapse in">
<div class="card-block card-dashboard">
<button id="addRow" class="btn btn-primary mb-2 js-create-employee"><i class="ft-plus"></i> Add New Employee</button>
<table class="table table-striped table-bordered zero-configuration">
<thead>
<tr>
<th>Name</th>
<th>Username</th>
<th>Roles</th>
<th>Email</th>
<th>Mobile Contact</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for profile in user_profile_list %}
<tr>
{% if not profile.user.is_superuser %}
<td>{{ profile.user.get_full_name }}</td>
<td>{{ profile.user.username }}</td>
<td>
{% for g in profile.user.groups.all %}
<div class="tag tag-default">{{ g.name|split:'_'|title }}</div>
{% endfor %}
</td>
<td>{{ profile.user.email }}</td>
<td>{{ profile.mobile_phone }}</td>
<td><i class="fa fa-pencil"></i> <a href="#" alt="Assign"><i class="fa fa-link"></i><a/> <a href="#" alt="delete"><i class="fa fa-times"></i><a/></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Username</th>
<th>Roles</th>
<th>Email</th>
<th>Mobile Contact</th>
<th>Actions</th>
</tr>
</tfoot>
</table>
Datatable instantiation:
$(document).ready(function() {
/****************************************
* js of zero configuration *
****************************************/
$('.zero-configuration').DataTable();
});
Jquery.datatables.min.js and dataTables.bootstrap4.min.js are also used, but those come stock from bootstrap 4. I'm not going to add them here unless needed, and they are minified anyway.
This issues occurs only when data is not available for the table or tags.
You have conditions in template using django templatestag So the number of every <td> element in your table that is a child of a <tr> element doesn't match the number of <th> elements that are a child of the element.
Please make sure you have same number of <td> tag in <tbody> tag.
EDIT:
Maybe {% if not profile.user.is_superuser %} this condition creating this issue. If user is superuser then no <td> tag will create that will not match same number of <th> in <thead>