Django template operations with if, with, for and math-add usage - python-2.7

I am trying to form a table in django template. One row will be white, other row will be gray... And it will go on like that. So the table rows will be displayed 1 white row, 1 gray row. So it will be more readable. I tried to set an integer variable to decide in which if condition what color the row will be. The colors are determined in class="tr1" and class="tr2" css classes. But it is always setting class="tr1". So always 1st if condition is working. Couldnt solve it.
{% with 0 as num %}
{% for note in notes %}
{% if num == 0 %}
<tr class="tr1">
<td class="td_size1">{{note.teacher__name}}</td>
<td class="td_size1">{{note.attendance}}</td>
<td class="td_size1">{{note.time}}</td>
<td class="td_size1">{{note.dailynote}}</td>
</tr>
{{ num|add:1 }}
{% endif %}
{% if num == 1 %}
<tr class="tr2">
<td class="td_size1">{{note.teacher__name}}</td>
<td class="td_size1">{{note.attendance}}</td>
<td class="td_size1">{{note.time}}</td>
<td class="td_size1">{{note.dailynote}}</td>
</tr>
{{ num|add:-1 }}
{% endif %}
{% endfor %}
{% endwith %}

I solved this by using css. There is also a javascript solution but it does not work if javascript disabled. In the css it checks , if it is odd or even. If it is odd it gives first color, if it is even it gives second color.
table.custom1 {
font-family: arial, sans-serif !IMPORTANT;
border-collapse: collapse !IMPORTANT;
width: 100% !IMPORTANT;
}
td.custom1, th.custom1 {
border: 1px solid #511327 !IMPORTANT;
text-align: left !IMPORTANT;
padding: 4px !IMPORTANT;
}
tr.custom1:nth-child(even) {
background-color: #701b36 !IMPORTANT;
}
tr.custom1:nth-child(odd) {
background-color: #5e172e !IMPORTANT;

Related

Is the "with" template nest-able in Django 2.2, and 3.2? HOw do I do that and work with forloop.counter as well?

I am referring to https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#with for Django 2.2 and https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#with for 3.2
Can i use them this way?
{% with
thStyle="font-size: 1.4em;text-align: left;background-color: #A7C942;color: #fff;border: 1px solid #98bf21;padding: 5px 7px 4px 7px;"
tdStyle="font-size: 1.2em;border: 1px solid #98bf21;padding: 3px 7px 2px 7px;"
alttdStyle = "font-size: 1.2em;border: 1px solid #98bf21;padding: 3px 7px 2px 7px; background-color: #EAF2D3;"
%}
....
{% for key, value in some_list.items %}
{% with style = tdStyle # when forloop.counter|divisible:2 else it's alttdStyle %}
....
{% endwith %}
{% endfor %}
{% endwith %}
My plan is taht i need to use different td style depending whether the counter is divisible by 2 or not.
This is my logic. not confident if correct.

Django Template inclusion tags, supress trailing newline

Firstly I know about {% spaceless %}. I don't want to remove all spaces. I just would like the inclusion tag to only render the template, and not add its own trailing '\n' at it's own discretion.
E.g. say I have the template tag:
from django import template
register = template.Library()
#register.inclusion_tag(f'myemail/button.html')
def myemail_button(href, title, color, background_color):
return {
'href': href,
'title': title,
'color': color,
'background_color': background_color,
}
And this is the inclusion tag's template (myemail/button.html):
<table><tbody><tr>
<td style="background-color:{{ background_color }}; border-radius:5px; border:solid 1px {{ background_color }}; color:{{ color }}; padding:0px;">
{{ title }}
</td>
</tr></tbody></table>
Then when one renders this template (there is no blank line at the start nor end of the file:
{% load myemail %}{% myemail_button href="https://example.com" title="CLICK ME!" color="#123456" background_color="#abcdef" %}
{% myemail_button href="https://example.com" title="CLICK ME!" color="#123456" background_color="#abcdef" %}
It renders as (note the space between the two adjacent <table> elements (this is the new line I would not like auto inserted):
<table><tbody><tr>
<td style="background-color:#abcdef; border-radius:5px; border:solid 1px #abcdef; color:#123456; padding:0px;">
CLICK ME!
</td>
</tr></tbody></table>
<table><tbody><tr>
<td style="background-color:#abcdef; border-radius:5px; border:solid 1px #abcdef; color:#123456; padding:0px;">
CLICK ME!
</td>
</tr></tbody></table>

How to hide 0 notification count in django-notifications-hq

I ham trying to hide the notification count when it's 0 in django-notifications-hq
I have tried the below method but it is not updating regularly and displaying the number correctly.
{% live_notify_badge as nc %}
{% if nc > 0|add:0 %}
<span class="badge-notifications badge badge-pill badge-danger" style="float:right;margin-bottom:-3px;margin-top: -2px !important; margin-left: 10px !important; font-size: 0.6rem;">
{% live_notify_badge %}</span>
{% endif %}
nc is not the number of notifications. It generates some HTML that will make Javascript calls to fetch the number of notifications.
You can obtain the number of unread notifications in the template with:
{{ user.notifications.unread.count }}
So we can check if an unread notification exists, and use this to render the {% live_notify_badge %}:
{% if user.notifications.unread.exists %}
<span class="badge-notifications badge badge-pill badge-danger" style="float:right;margin-bottom:-3px;margin-top: -2px !important; margin-left:10px !important; font-size: 0.6rem;">
{% live_notify_badge %}
</span>
{% endif %}
Note however that this will be rendered at server side, so that means that when the user fetches the page, and there are no notifications, it will not display the badge. If however later there are notifictions these will not be rendered.

Twig zebra-stripping without loop

I have a table whose rows are generated dynamically depending on users' input (it is a summary of charges that may or may not take a promo code--if the user have one--and a gift message--if the user sends one). There is no way to generate the items of the summary of charges on a loop since the items come from different places in my application. I only have conditionals for the items to appear or not on the users' order depending on what the order is like. The table needs to have zebra-stripping. Because the number of items may vary, I cannot hardcode the color inline (it is an e-mail). I tried twig's divisibleby and modulo on the rows, so the colors would alternate for even and odd rows. Although the color changes it does not change to the color I want and it is not doing the zebra stripping (all rows change to blue. I need colors to alternate between light beige (#fcf9f5) and white (#ffffff)). What am I missing?
Here is the code for one tr:
{% set index = 0 %}
<tr bgcolor="{% if index is divisibleby(2) %} #fcf9f5 {% else %} #ffffff {% endif %}">
<td align="left" style="height: 30px; width: 273px; padding-left: 40px;">
<span style="font-family:'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial,'Lucida Grande', sans-serif;font-weight: 500;">Order Subtotal:</span>
</td>
<td align="left" style="height: 30px; width: 273px; padding-left: 40px;font-family:'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial,'Lucida Grande', sans-serif; font-weight: 300;">
<span>{{ order.itemsTotal|sylius_price }}</span>
</td>
</tr>
{% index++ %}
Sorry but Twig can't correct the fact that your code is dirty.
Let's say you have 3 diferents sources. If you display them all in an array they have all comon attributes right?
you just have to combine all the source objects in a simple displayable object (a DTO).
Twig can't contain business logic, it just display stuff.
If you want to keep your logic in your view, try to use twig merge fuction to combien your arrays and display them in a loop

Trouble getting django-chosen ChosenSelect widget to work

I'm trying to set up a ModelForm in Django that will use the django-chosen ChosenSelect widget for one of the fields. I have installed django-chosen and this is the code I have:
class TestForm(ModelForm):
class Meta:
model = Test
widgets = {
'field': chosenwidgets.ChosenSelect(),
}
However, the specifying the widgets has no effect and the form is outputted the same regardless of whether I define it. Any suggestions?
Are you including the form media in your template?
The example template below assumes that your base template has blocks extrastyle and extrahead where you include CSS and scripts respectively, and that you have included jquery 1.4+ in your base template.
# my_template.html
{% extends "base.html" %}
{% block extrastyle %}
{{ block.super }}
{{ form.media.css }}
{% endblock %}
{% block extrahead %}
{{ block.super }}
{{ form.media.js }}
{% endblock %}
{% block content %}
<form action="." method="post">
<table>
{{ form }}
</table>
<p><input type="submit" value="Update" />
</form>
{% endblock %}
Here is my solution with using chosen.js directly. I installed it with bower and then included it in my admin class Media:
class MyModelAdmin(LockableAdmin, admin.ModelAdmin):
form = MyModelForm # has phase_id field
class Media:
js = ('components/chosen_v1.1.0/chosen.jquery.min.js', 'admin_tools/js/chosen_admin.js')
css = {'all': ('components/chosen_v1.1.0/chosen.min.css', 'admin_tools/css/chosen_admin.css')}
The additional chosen_admin.js and chosen_admin.css files contain my init script and css for making the select look more like django admin. Here are the contents:
chosen_admin.js:
/* Create own jquery namespace */
var django = {
"jQuery": django.jQuery.noConflict(true)
};
var jQuery = django.jQuery;
var $=jQuery;
$( document ).ready(function() {
$('#id_phase_id').chosen();
});
chosen_admin.css (optional):
a.chosen-single {
box-shadow: none;
border-radius: 0px;
background: white;
background-image: none;
}
a.chosen-single span{
line-height: 18px !important;
}
.vTextField{
width: 24em;
}
a.chosen-single, .chosen-container.chosen-container-single, .chosen-container-single.chosen-single{
position: absolute;
box-shadow: none !important;
border-radius: 0px !important;
background: white !important;
background-image: none !important;
font-size: 11px !important;
height: 18px !important;
padding-left: 2px !important;
}
.chosen-container-single .chosen-single div b {
background-position: 0px 0px;
}
I got some insights here and made corrections as needed. Also see chosen.js. Hope this helps :)