Django Calculation inside HTML - django

I wanted to do something simmilar to this suing django. but somehow i it doesn't work. how do i fix it?
for statik in statistik{
print(statik*total/100)
}
Is there any documentation regarding what I'm trying to implement to my django app? Thank you
Here's the HTML :
{% if statistics %}
{% for statik in statistics|slice:":4" %}
<div class="mb-3">
<div class="small text-gray-500">{{ statik.name }}
<div class="small float-right"><b>{{ statik.voters }} of {{ total }} Voters</b></div>
</div>
<div class="progress" style="height: 12px;">
<div class="progress-bar bg-success" role="progressbar" style="width: {{ statik.voters * total/100 }}%" aria-valuenow="50"
aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
{% endfor %}
{% else %} <p>END TABLE</p>
{% endif %}

It is recommended you do calculations of any sort in view and pass it in context.
If you still want to go this route there are no math template tags except add included so you should create custom template tags or use django-mathfilters

Related

How to customise task context (process_data cards) in django-viewflow

What I want
I'm building an approval workflow using django-viewflow and django-material.
The individual tasks are rendered as a main form with context on a very narrow column on the right-hand side.
I want to change the layout so that the task context (the detail views of all involved model instances) is better readable to the user, and also customise which fields are shown (eg. exclude a user's password hash).
Where I'm stuck
Is there a way to override which data is available as process_data short of overriding viewflow's get_model_display_data and include_process_data? E.g. I'd like to have the related instance's __str__() as title.
Does viewflow have any canonical way to provide individual detail card templates? My alternative would be to completely re-work the contents of the process_data sidebar using context['process'] as the central instance, but that would tie the templates to the data model.
Are django-material formsets with read-only fields and a custom layout the answer I'm after? (I will try this out as soon as I have a viewflow pro license.)
I'd be grateful on any pointers here.
What I've tried
I'm overriding/extending the viewflow templates. As per templatetag include_process_data, the template process_data.html supplies the column of model instance detail cards, fed by data from
get_model_display_data.
It's e.g. easy to override process_data.html to change the cards into a MaterializeCSS collapsible list:
{% load i18n viewflow material_frontend viewflow_frontend %}
<!--
This is template "APP_NAME/PROCESS_NAME/process_data.html" overriding "viewflow/flow/process_data.html".
We override instead of extending as "viewflow/flow/process_data.html" has no content block.super
Changes:
* Collapsible list of process context instead of cards.
-->
<script type="text/javascript">
$(document).ready(function () { $('.collapsible').collapsible(); });
</script>
<ul class="collapsible">
{% for root, fields, root_url in process_data %}
<li>
<div class="collapsible-header">
<span class="card-title">{{ root }} #{{ process.pk }}</span>
{% if root_url and request.user.is_staff %}
<a href="{{ root_url }}" class="card-edit" target="_blank" data-turbolinks="false" style="float:right">
{% trans 'edit' %}
</a>
{% endif %}
</div>
<div class="collapsible-body process_data_content">
<dl class="dl-horizontal">
{% for name, value in fields %}
<dt>{{ name }}:</dt>
<dd>
{% if value is True %}{% trans 'Yes' %}{% else %}
{% if value is False %}{% trans 'No' %}{% else %}
{% if value and value.url %}{{ value.name }}{% else %}
{{ value }}{% endif %}{% endif %}{% endif %}
</dd>
{% endfor %}
</dl>
</div>
{% if not hide_active_tasks and forloop.counter == 1 and process.active_tasks %}
<li>
<div class="collapsible-header">
<span class="card-title">{% trans 'Active tasks' %}</span>
</div>
<div class="collapsible-body process_data_content">
<table>
<thead>
<tr>
<th>{% trans 'Task' %}</th>
<th>{% trans 'Owner' %}</th>
</tr>
</thead>
<tbody>
{% for task in process.active_tasks %}
{% if task.flow_task.task_type == 'HUMAN' or task.flow_task.task_type == 'JOB' %}
<tr>
<td>
{{ task.flow_task}}/#{{ task.pk}}
</td>
<td>{{ task.owner|default:"" }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</li>
{% endif %}
</li>
{% endfor %}
</ul>
Overriding the template viewflow/flow/task.html with my own APP_NAME/PROCESS_NAME/TASK_NAME.html template at the cost of including model-specific information can show e.g. customised cards of related instances over the main form. I would refactor the individual cards into their own templates.
{% extends "viewflow/flow/task.html" %}
{% block left-panel__top %}
<!--
This is template "APP_NAME/PROCESS_NAME/TASK_NAME.html" extending "viewflow/flow/task.html".
-->
<!-- Help specific to this step goes here. -->
{% with activation.process as p %}
<div class="row">
<h3>Nested formsets</h3>
<p>These cards are placeholders for formsets nested within the main application form.</p>
<p>Nested formsets and the main application form can be updated at the same time and have exactly one submission button.</p>
</div>
<div class="row">
<!-- Organisation Questions: Answers -->
<!-- TODO refactor to template include -->
{% for x in p.organisationanswer_set.all %}
<div class="col s12 m6 xl4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">
{{ x.question.question }}
</span>
<p><strong>Your answer:</strong> {{ oa.answer }}</p>
</div>
<div class="card-action">
Provide an answer
</div>
</div>
</div>
{% endfor %}
<!-- Dataset Questions: Answers -->
{% for x in p.datasetanswer_set.all %}
<div class="col s12 m6 xl4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">
{{ x.question.question }}
</span>
<p><strong>Your answer:</strong> {{ x.answer }}</p>
</div>
<div class="card-action">
Provide an answer
</div>
</div>
</div>
{% endfor %}
<!-- Approvals: Receipts - TODO show this in task after custodian approval -->
{% for x in p.approvalreceipt_set.all %}
<div class="col s12 m6 xl4">
<div class="card blue-grey darken-1">
<div class="card-content white-text">
<span class="card-title">
{{ x.approval }}
</span>
<p><strong>Your approval receipt:</strong> {{ x.receipt }}</p>
</div>
<div class="card-action">
Provide an answer
</div>
</div>
</div>
{% endfor %}
</div>
{% endwith %}
<div class="row">
<h3>Main application form</h3>
<p>These main application form would include the forms above as nested formsets.</p>
<p>This note will disappear once this has been implemented.</p>
</div>
{% endblock %}
For the basic cases create a template named as [app_label]/[flow_label]/process_data.html For example check the shipment demo
Viewflow is the thin workflow layer on top of the standard Django model-view-template pattern. Any customization practices for Django are valid for Viewflow
For the complex cases it's better to not to tune some universal implementation, but create your own set of templates for Viewflow, ex cookbook/custom_ui

Django templates avoid loop

I am working on a project and I have a slight confusion.
The Django Template index.html has following code:
<div class="carousel-item active">
{% for i in products|slice:"0:"%}
<div class="col-xs-3 col-sm-3 col-md-3">
<div class="card" style="width: 17rem;">
<div class="card-body">
{% for img in i.images.all %}
{% if forloop.counter == 1 %}
<img src={{img.img_url}} class="card-img-top" alt="...">
{% endif %}
{% endfor %}
<h6 class="card-title">{{i}}</h6>
{% for skus in i.skus.all %}
{% if forloop.counter == 1 %}
<h6 class="card-price">{{skus.price}} {{skus.currency}}</h6>
{% endif %}
{% endfor %}
Add to Cart
</div>
</div>
</div>
{% endfor %}
</div>
In this code, is there a way to eliminate the {% for skus in i.skus.all %}?
The all tag is getting all objects, but I am restricting the loop to run only one time through the if condition so that I can only get the first item.
Is there a way to eliminate the loops that have .all in them and restrict the statement to run only one time though any other way?
You can achieve by using either with tag to set a variable or direclty us as:
{% with skus=i.skus.first %}
<h6 class="card-price">{{skus.price}} {{skus.currency}}</h6
{% endwith %}
or
<h6 class="card-price">{{i.skus.first.price}} {{i.skus.first.currency}}</h6
You may be looking for the first queryset method:
<div class="card-body">
<img src={{i.images.first().img_url}} class="card-img-top" alt="...">
</div>

Invalid block tag on line 66: 'endblock', expected 'empty' or 'endfor'. Did you forget to register or load this tag?

Why is it giving me this strange error: Did you forget to register or load this tag? it was working fine but when i did some changes in this code it started this error... i was going through question related to this issue but could not find the solution....
<div class="container">
<div class="row">
<div class="pagination">
{% for item in post.object_list %}
<!-- {% for item in post %}-->
<div class="card my-3 text-white bg-dark mb-3" style="width: 18rem;">
<img src="/media/{{item.thumbnail}}" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
<p class="card-text">{{item.intro}}</p>
<!-- href={% url 'bicep' %}-->
read more...
<!-- read more...-->
</div>
</div>
{% if forloop.counter|divisibleby:4 %}
</div>
{% endif %}
{% endfor %}
Django disregards HTML comments. That means django will run this code:
<!-- {% for item in post %}-->
This is what's causing the error because django is expecting an endfor closing tag for this loop.
Either remove this line from your code or use django's comment template tag to comment out the template related code:
{% comment %}
{% for item in post %}
{% endcomment %}

How to bring data from DB of a User into form to update it

I'm studying django and trying to make a simple CRUD, following the djangoGirls tutorial. But unfortunatelly they don't show how to UPDATE data.
I'm already Inserting, Reading/listing how may I Delete and Update?
I listed the users with a link to edit it:
{% extends 'bloodDonation/master.html' %}
{% block content %}
<h1 class="center">LIST DONATORS<h1>
<ul>
{% for donator in donators %}
<div class="row">
<div class="container">
<div class="col s12 blue-grey lighten-5 border_lighten">
<div class="col s12 m12 padding_normal">
{{ donator.name }}
<div id="icon" class="right">
<i class="material-icons">edit</i>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</ul>
{% endblock %}
As you can see, I have an a tag pointing to edit_donator url.
How may I pass the ID/data of the selected/clicked user so I can pull his data and throw it inside the form?
Form creation:
class EditDonatorForm(forms.ModelForm):
class Meta:
model = Donator
fields = [ 'name', 'age', 'email', 'phone', 'bloodType', 'observation' ]
Trying to pass the ID:
url(r'^donator/(?P<pk>\d+)/update/$', views.edit_donator, name='edit_donator'),
How may I get data from database and already place it inside form so I can perform an Update?
You don't require to send the data to another link. You can update the details on the same URL.
Change your HTML to this:
{% extends 'bloodDonation/master.html' %}
{% block content %}
<h1 class="center">LIST DONATORS<h1>
<ul>
{% for donator in donators %}
<div class="row">
<div class="container">
<div class="col s12 blue-grey lighten-5 border_lighten">
<div class="col s12 m12 padding_normal">
{{ donator.name }}
<div id="icon" class="right">
<i class="material-icons">edit</i>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</ul>
{% endblock %}
In your view write,
if 'edit-donator' in request.GET:
edit_data = YourModel.objects.get(id=request.GET['edit-donator'])
form = EditDonatorForm(instance=edit_data)
This will get the data from the model and pass it to the template.
Now you can perform the update.
Hope this helps :)

django endless pagination making the second page to use different css in bootstrap

I am using django-endless-pagination with twitter style pagination and twitter bootstrap on my website.
Now, with django-endless-pagination, when the first page is displayed, system is using the below style.
.row-fluid .offset1:first-child {
margin-left: 8.547008547008547%;
}
But from the second page onwards, the style used for the first element is as below.
.row-fluid .offset1 {
margin-left: 11.11111111111111%;
}
As the margin-left is different for both pages first element, the rows are not aligned between page 1 and page 2. How do i change this, so that second page first element also uses first-child style and it is aligned.
Edit :-
My code looks like below in the template
<div class="offset1 span10">
<div class="span4">
{% lazy_paginate column_1_items_list %}
{% if column_1_items_list %}
{% for column_1_item in column_1_items_list %}
<div class="row-fluid image_div" style="padding-top:20px">
<h4 class="text-center">name_of_item</h4>
<a target="_blank" href="link_for_item">
<img class="item-size" src="photo.url" alt="name_of_item "/>
</a>
<p> quick_summary|safe </p>
<div class="row-fluid bottom">
<span class="price"><b>£ price</b></span>
</div>
</div>
{% endfor %}
{% endif %}
{% show_more " " %}
</div>
</div>
Thanks
Sreekanth
You could probably just use forloop.first and add a class to your css.
{% for column_1_item in column_1_items_list %}
<div class="row-fluid image_div{% if forloop.first %} first_child{% endif %}" style="padding-top:20px">
...
{% endfor %}