Django Regoup - Sum in templates - django

I want to get the Volume subtotal of my "Contracts" field grouped in my template.
I manage to display the total but not the subtotal.
Here are my files:
views.py
class TransportDetListView(LoginRequiredMixin,ListView):
login_url = 'admin:login'
model = TransColisCgDlaDet
template_name = "betou/transports/sciages/trans_detail.html"
paginate_by = 15
def get_queryset(self):
queryset = TransColisCgDlaDet.objects.filter(code_trans__contains=self.kwargs['code_trans']).order_by('num_contrat','essence','epaisseur')
lstcolis = queryset.values(
'num_colis',
'essence',
'epaisseur',
'qualite',
'produit',
'num_contrat',
'code_specif',
'code_specif_douane',
'destinataire',
'port_destination',
'marque',
'receptionnaire',
'code_trans'
).annotate(volumecolis=Sum('cubage')).annotate(nb_elts=Sum('nbre_elts'))
return lstcolis
def get_context_data(self, **kwargs):
context = super(TransportDetListView, self).get_context_data(**kwargs)
context['codetrans_filter'] = TransColisCgDlaDet.objects.filter(code_trans__contains=self.kwargs['code_trans']).order_by('num_contrat','essence','epaisseur')
context['nbrecolis'] = context['codetrans_filter'].values('num_colis').order_by('num_contrat').aggregate(nbrecolis=Count('num_colis')).get('nbrecolis')
context['totalvolume'] = context['codetrans_filter'].values('cubage').aggregate(totalvolume=Sum('cubage')).get('totalvolume')
context['totalelts'] = context['codetrans_filter'].values('nbre_elts').aggregate(totalelts=Sum('nbre_elts')).get('totalelts')
context['contrats'] = context['codetrans_filter'].annotate(volumecolis=Sum('cubage')).annotate(nb_elts=Sum('nbre_elts'))
return context
template
{% regroup contrats by num_contrat as lst_group %}
<table class="table table-responsive table-bordered text-center">
{% for group_ct in lst_group %}
<thead>
<tr>
<td colspan = "15" class="align-center" style="font-weight: 600">{{ group_ct.grouper }}</td>
</tr>
<tr>
<tr>
<th>N.Contrat</th>
<th>Essence</th>
<th>Epais.</th>
<th>N.Colis</th>
<th>Nb Elts</th>
<th>Volume</th>
<th>Qualité</th>
<th>Produit</th>
<th>Specif</th>
<th>Specif Douane</th>
<th>Destinataire</th>
<th>Destination</th>
<th>Marque</th>
<th>Réceptionnaire</th>
<th>Code Trans</th>
</tr>
</thead>
<tbody>
{% for trans in group_ct.list %}
<tr>
<td>{{trans.num_contrat|default_if_none:""}}</td>
<td>{{trans.essence}}</td>
<td>{{trans.epaisseur}}</td>
<td>{{trans.num_colis}}</td>
<td style="text-align: right;">{{trans.nb_elts}}</td>
<td style="text-align: right;">{{trans.volumecolis}}</td>
<td>{{trans.qualite|default_if_none:""}}</td>
<td>{{trans.produit|default_if_none:""}}</td>
<td >{{trans.num_contrat}}&nbsp{{trans.code_specif}}</td>
<td>{{trans.code_specif_douane|default_if_none:""}}</td>
<td>{{trans.destinataire|default_if_none:""}}</td>
<td>{{trans.port_destination|default_if_none:""}}</td>
<td>{{trans.marque|default_if_none:""}}</td>
<td>{{trans.receptionnaire|default_if_none:""}}</td>
<td>{{trans.code_trans}} {% if not forloop.last %}{% endif %}</td>
</tr>
{% endfor %}
<tr>
<td colspan = "3" style="text-align: center; font-weight: 600;">TOTAUX:</td>
<td style="text-align: right; font-weight: 600;">{{ group_ct.list|length }} Colis</td>
<td style="text-align: right; font-weight: 600;">{{ group_ct.list.nb_elts }}</td>
<td style="text-align: right; font-weight: 600;"> {{ group_ct.list.volumecolis }}</td>
<td colspan = "12"></td>
</tr>
{% endfor %}
<tr>
<td colspan = "3" style="text-align: center; font-weight: 600;">TOTAUX:</td>
<td style="text-align: right; font-weight: 600;">{{ nbrecolis }} Colis</td>
<td style="text-align: right; font-weight: 600;">{{ totalelts }}</td>
<td style="text-align: right; font-weight: 600;"> {{ totalvolume }}</td>
<td colspan = "12"></td>
</tr>
</tbody>
</table>
I get this result:
screenshot browser
You see that the Parcel count is done correctly {{ group_ct.list|length }}. But for the sum I don't have a subtotal result.
Thanks

Related

Django about Different templates have different results

I'm a super newbie, so please refer to this and read it.
I am creating a bulletin board that communicates by DB <> API <> WEB method.
Successfully import comments with comment.html.
However, comments cannot be imported at {%inlude%} in boardapi_detail.html.
Please refer to the picture at the bottom of the article.
view.py
class Commentapi_list(generic.TemplateView):
def get(self, request, *args, **kwargs):
data = {
'pk': self.kwargs['pk'],
}
url = 'http://127.0.0.1:8080/boardapi/' + str(data['pk']) + '/comment/'
datas = requests.get(url, params=data).json()
# print(datas)
# print(type(datas))
df = pd.DataFrame(datas)
clist = [tuple(r) for r in df.to_numpy()]
print(clist)
# print(type(clist))
return render(self.request, 'comment_form.html', {
'comment_list' : clist
})
urls.py
path('board/<int:pk>/', views.Boardapi_detail.as_view(), name="board_detail")
comment.html
{% if not comment_list %}
<p class="text-center"> There is no comment. </p>
{% endif %}
<div style="margin:20px 0;">
{% for i in comment_list %}
<table width="100%" cellpadding="0" cellspacing="0" class="tbl_replist" id="reply_list_layer">
<tbody>
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td style="padding-left: 10px;border-top: 1px solid #eee;width: 114px;">{{ i.1 }}</td>
<td style="vertical-align: top;border-top: 1px solid #eee;padding: 10px 0;">{{ i.2 }}
<span style="color: #999;font-size: 11px;display: block;">{{ i.3 }}</span>
</td>
</tr>
{% if user.username == i.c_writer or user.is_staff %}
delete
{% endif %}
</tbody>
</table>
{% endfor %}
</div>
boardapi_detail.html
{% if not board_detail %}
<p class="text-center">There's nothing. </p>
{% else %}
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td width="20%" align="center">title</td>
<td width="80%" align="left">{{ board_detail.b_title }} </td>
</tr>
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td width="20%" align="center">writer</td>
<td width="80%" align="left">{{ board_detail.b_writer }} </td>
</tr>
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td width="20%" align="center">note</td>
<td width="80%" align="left">{{ board_detail.b_note }}</td>
</tr>
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td width="20%" align="center">time</td>
<td width="80%" align="left">{{ board_detail.b_date }} </td>
</tr>
<tr style="height:60px;border-top:solid 1px #dddddd;" align="center">
<td width="100%" colspan="2">
edit
<button class="btn btn-outline-success my-2 my-sm-0" style="margin-right:10px;" onclick="location.href='/board/'">list</button>
</td>
</tr>
<tr style="height:45px;border-top:solid 1px #dddddd;">
<td width="20%" align="center">comment</td>
<td width="80%" align="left">({{ board.comment_set.all.count }})</td>
</tr>
</table>
{% endif %}
{% include "comment.html" %}
The pictures below are about the first article each.
comment.html page
↑Successfully imported all 3 comments.
boardapi_detail.html page
↑couldn't get even one comment.

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-mptt display hierarchy as table

I am trying to display a hierarchical table as a normal table.
model.py
class Dimension_value(MPTTModel):
name = models.CharField(max_length = 200, null=True, blank = True, default = '')
parent = TreeForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, related_name="children")
class MPTTMeta:
order_insertion_by = ['name']
def __str__(self):
return self.name
views.py
def show_genres(request):
return render(request, "accounts/dimension_detail.html", {'dimensions': Dimension_value.objects.all()})
dimension_detail.html
<div class="container-fluid">
<div class="card">
<div class="card-body">
<h2>My dimensions</h2>
{% load mptt_tags %}
<ul>
{% recursetree dimensions %}
<li>
{{ node.name }}
{% if not node.is_leaf_node %}
<ul class="children">
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
</div>
</div></div>
Using django-mptt the lists show just fine. However I have no idea how to display this in a normal table.
For example
Europe|The Netherlands|Noord-Holland
Europe|The Netherlands|Zuid-Holland
Europe|Belgium|Vlaanderen
what I currently get
<table>
<thead>
<tr>
<th class="id orderable">ID</th>
<th class="name orderable">Name</th>
<th class="orderable parent">Parent</th>
<th class="asc lft orderable">Lft</th>
<th class="orderable rght">Rght</th>
<th class="asc orderable tree_id">Tree Id</th>
<th class="level orderable">Level</th>
</tr>
</thead>
<tbody>
<tr class="even">
<td class="id">6</td>
<td class="name">Asia</td>
<td class="parent">—</td>
<td class="lft">1</td>
<td class="rght">4</td>
<td class="tree_id">1</td>
<td class="level">0</td>
</tr>
<tr class="odd">
<td class="id">8</td>
<td class="name">Japan</td>
<td class="parent">Asia</td>
<td class="lft">2</td>
<td class="rght">3</td>
<td class="tree_id">1</td>
<td class="level">1</td>
</tr>
<tr class="even">
<td class="id">5</td>
<td class="name">Europe</td>
<td class="parent">—</td>
<td class="lft">1</td>
<td class="rght">8</td>
<td class="tree_id">2</td>
<td class="level">0</td>
</tr>
<tr class="odd">
<td class="id">7</td>
<td class="name">Belgium</td>
<td class="parent">Europe</td>
<td class="lft">2</td>
<td class="rght">7</td>
<td class="tree_id">2</td>
<td class="level">1</td>
</tr>
<tr class="even">
<td class="id">9</td>
<td class="name">Vlaanderen</td>
<td class="parent">Belgium</td>
<td class="lft">3</td>
<td class="rght">4</td>
<td class="tree_id">2</td>
<td class="level">2</td>
</tr>
<tr class="odd">
<td class="id">10</td>
<td class="name">Wallonie</td>
<td class="parent">Belgium</td>
<td class="lft">5</td>
<td class="rght">6</td>
<td class="tree_id">2</td>
<td class="level">2</td>
</tr>
</tbody>
</table>

Interval in Django template

I have an interval type field that contains hours and minutes in this format: "28:00".
But in my template, it is translated to "1 day, 4:00:00"
How can I keep this "28:00" in my template?
My template:
<table class="table table-bordered ">
<thead align="center">
<th class="text-center" scope="col">User</th>
<th class="text-center" scope="col">Week number</th>
<th class="text-center" scope="col">Total H</th>
</thead>
<tbody>
{% for tp in resume_h %}
<tr scope="row">
<td class="text-center col-md-1">{{ tp.user_name }}</td>
<td class="text-center col-md-1">{{ tp.num_semaine }}</td>>
<td class="text-center col-md-1">{{ tp.hours_total|linebreaksbr }}</td>
</tr>
{% endfor %}
</tbody>
</table>
My model:
class hours(models.Model):
user_name = models.CharField(max_length=50, blank=True, null=True)
num_semaine = models.IntegerField(("No:"),blank=True, null=True)
hours_total = models.TimeField(("H"),blank=True, null=True)
def __str__(self):
return str(self.user_name)
Thank you

Django reportlab insert pagebreak html-side

I'm trying to insert a pagebreak after a table in a pdf I'm generating with reportlab, I'm using the following function to generate the pdf:
def render_to_pdf(template_src, context_dict):
template = get_template(template_src)
context = Context(context_dict)
html = template.render(context)
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), dest=result, link_callback=fetch_resources)
if not pdf.err:
return result.getvalue()
return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))
def fetch_resources(uri, rel):
return os.path.join(MEDIA_ROOT, uri.replace(MEDIA_URL, ""))
I'm calling the function from a view this way:
#login_required(login_url=reverse('accounts:login_box'))
def quote_pdf(request, quote_id):
data_pdf = {}
quote = get_object_or_404(Quote, id=quote_id)
data_pdf['pagesize'] = 'letter'
data_pdf['quote'] = quote
pdf = render_to_pdf('rents/quote_pdf.html', data_pdf)
return HttpResponse(pdf, mimetype='application/pdf')
And this is my template (quote_pdf.html)
{% load humanize compress verbatim %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Cotización No. {{ quote.id }} Flasherz.co/alquiler</title>
<style type="text/css">
#page {
size: {{ pagesize }};
margin: 1cm;
#frame footer {
-pdf-frame-content: footerContent;
bottom: 0cm;
margin-left: 0cm;
margin-right: 0cm;
height: 0cm;
}
}
</style>
<style type="text/css">
body {
font-size: 12px;
line-height: 13px;
}
div#pdf-header {
display: block;
}
div#pdf-header h2 {
display: block;
text-align: center;
font-weight: normal;
line-height: 35px;
font-size: 18px;
}
div#pdf-quote-info {
display: block;
margin-bottom: 20px;
}
p {
margin: 0;
}
table {
border-top: 1px solid #eee;
}
table td, table th {
border-right: 1px solid #eee;
border-bottom: 1px solid #eee;
padding: 5px;
border-left: 1px solid #eee;
}
table .price {
text-align: right;
}
table th {
padding: 5px 0;
font-size: 13px;
text-transform: uppercase;
color: black;
text-align: left;
background-color: #eee;
padding-left: 5px;
}
table p.description {
color: #555;
font-size: 11px;
}
table#quote-info {
border: none;
}
table#quote-info td, table#quote-info th {
border: none;
padding: 0;
}
table td.quantity {
text-align: center;
}
</style>
</head>
<body>
<div id="pdf-header">
<div style="width: 100%; text-align: center;">
<img src="{{ STATIC_URL }}img/quotes-logo.jpeg" alt="Flasherz.co Alquiler" width="600" height="126" />
<div style="display: block; text-align: center; margin: 10px 0;">
<h2>Cotización No. {{ quote.id }}, {{ quote.client_name }}</h2>
</div>
</div>
</div>
<div id="pdf-quote-info">
<table id="quote-info" width="70%" border="none" cellpadding="3" cellspacing="0">
<tr>
<td width="25%">Fecha:</td>
<td width="75%">{{ quote.created|date:'l j' }} de {{ quote.created|date:'F' }} de {{ quote.created|date:'Y' }}</td>
</tr>
{% if quote.client_name %}
<tr>
<td>Cliente:</td>
<td>{{ quote.client_name }}</td>
</tr>
{% endif %}
{% if quote.client_email %}
<tr>
<td>Correo:</td>
<td>{{ quote.client_email }}</td>
</tr>
{% endif %}
{% if quote.client_address %}
<tr>
<td>Dirección:</td>
<td>{{ quote.client_address }}</td>
</tr>
{% endif %}
{% if quote.client_phone %}
<tr>
<td>Teléfono:</td>
<td>{{ quote.client_phone }}</td>
</tr>
{% endif %}
<tr>
<td>Cantidad de días:</td>
<td>{{ quote.rental_days }}</td>
</tr>
</table>
</div>
</div>
<div id="pdf-quote-table">
<table id="quote-table" cellpadding="0" cellspacing="0" width="100%">
{% for category in quote.categories.all %}
<tbody>
<tr>
<th colspan="4" class="category-header">{{ category.category.name }}</th>
</tr>
{% for item in category.items.all %}
<tr>
<td class="quantity" width="10%">
<p>{{ item.quantity }}</p>
</td>
<td class="name" width="50%">
<p class="name">{{ item.name }}</p>
{% if item.content %}<p class="description">{{ item.content }}</p>{% endif %}
</td>
<td class="price" width="20%">
<p>${{ item.price|intcomma }}</p>
</td>
<td class="price total-price" width="20%">
<p>${{ item.total_price|intcomma }}</p>
</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
<tbody id="others">
<tr>
<th colspan="4" class="category-header">Seguro del 10%</th>
</tr>
<tr>
<td class="quantity"></td>
<td class="name">Seguro 10%</td>
<td class="price"></td>
<td class="price total-price">
<p>${{ quote.get_insurance_price|intcomma }}</p>
</td>
</tr>
</tbody>
{% if quote.discount %}
<tbody id="others">
<tr>
<th colspan="4" class="category-header">Descuento</th>
</tr>
<tr>
<td class="quantity">
</td>
<td class="name">Descuento</td>
<td class="price"></td>
<td class="price total-price">
<p>${{ quote.discount|intcomma }}</p>
</td>
</tr>
</tbody>
{% endif %}
<tbody id="totals">
<tr>
<th colspan="4" class="category-header">Total</th>
</tr>
<tr>
<td class="fake" colspan="2"></td>
<td class="name">Subtotal</td>
<td class="price">
<p>${{ quote.get_subtotal|intcomma }}</p>
</td>
</tr>
<tr>
<td class="fake" colspan="2"></td>
<td class="name">Total días</td>
<td class="price">
<p>${{ quote.get_total_days|intcomma }}</p>
</td>
</tr>
<tr>
<td class="fake" colspan="2"></td>
<td class="name">Total</td>
<td class="price">
<p><strong>${{ quote.get_total|intcomma }}</strong></p>
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
I don't know the way to insert a pagebreak after the table to insert the "terms and conditions" in the next page.
Also I have a problem with the images in the pdf, no one is appearing when rendered.
Thanks for helping me
From what I've learned in Pisa's documentation (and this forum post), you can use standard CSS tags like page-break-after and page-break-before. Pisa also has some of it's own tags, like pdf:nextpage. To use this, simply insert the following code block where you would like the page break (the div's are necessary so Pisa's HTML5 parser doesn't try to interpret them):
<div>
<pdf:nextpage />
</div>
I've found the correct method to do it, I needed to insert a few specific styles in the of my pdf
<style type="text/css">
#page {
size: {{ pagesize }};
margin: 1cm;
#frame footer {
-pdf-frame-content: footerContent;
bottom: 0cm;
margin-left: 0cm;
margin-right: 0cm;
height: 0cm;
}
}
.page-break{
page-break-after: always;
}
</style>
Then put a element with .page-break class in where you want to have a page break in your pdf.
I had no luck with the css method.
Just insert this bit of code in your template.html wherever you want a page break. It works for me. I'm not sure, but I think it has to be in a div.
<div>
<pdf:nextpage />
</div>