Django templates: Group items in Threes
Whenever you find yourself trying out complex code inside templates, its usually a good indication that it should be moved elsewhere. One of the alternative solutions have already been suggested, which is to move the code into your view function.
The other solution would be to expose the functionality via a new template tag. One of the reasons you would choose this solution over the view solution, is that you'll be able to easily re-use the code for pages that are served with different views.
class GroupPaintingsNode(template.Node):
def __init__(self, num, varname):
self.num, self.varname = int(num), varname
def render(self, context):
paintings = Painting.objects.all # do your fetching/filtering here..
l = [[] for i in range(len(paintings))]
i = 0
while i < len(paintings):
l[i].append([p.title for p in paintings[i:i+self.num]])
l[i].append([p.desc for p in paintings[i:i+self.num]])
i += self.num
context[self.varname] = l
return ''
def group_paintings(parser, token):
tokens = token.contents.split()
if len(tokens) != 4:
raise template.TemplateSyntaxError, "'%s' tag requires three arguments" % tokens[0]
if tokens[2] != 'as':
raise template.TemplateSyntaxError, "Second argument to '%s' tag must be 'as'" % tokens[0]
return GroupPaintingsNode(tokens[1], tokens[3])
group_paintings = register.tag(group_paintings)
In template code you would use it like this:
{% group_paintings 3 as paintings %}
{% for p in paintings %}
{% for title in p.0 %} {{ title }} {% endfor %}<br>
{% for desc in p.1 %} {{ desc }} {% endfor %}
{% endfor %}
Use Django view to group every 3 objects into seperate context variables?
You can "unpack" the elements in separate variables:
def project_index(request):
projects = Project.objects.all()
project_len = len(projects)
# for nine elements
group1, group2, group3 = zip(*[iter(projects)]*3)
context = {
'projects': projects,
'group1': group1,
'group2': group2,
'group3': group3
}
return render(request, 'project_index.html', context)
or with an arbitrary number of elements:
def project_index(request):
projects = Project.objects.all()
project_len = len(projects)
groups = zip(*[iter(projects)]*3)
context = {
'projects': projects,
**{f'group{i}': val for i, val in enumerate(groups, 1)}
}
return render(request, 'project_index.html', context)
That being said, passing these as individual elements, might not be a good idea. Since at the template end, you then will somehow have to access it. Therefore it might be better to pass it as an iterable of iterables, and thus use two nested loops in the template.
Django: Can't GROUP BY on a template table
I'm not entirely sure what you're trying to do. It's either to total up each date or to sum all totals. I've provided ways to do both.
from django.db.models import F, Sum, Count
resultado = Asiento.objects.filter(
Empresa=request.session['codEmp'],
codcta=cod_cta
).exclude(anulado='S').order_by(date).values('date').annotate(
dcount=Count('date'),
add_sum=Sum('add'),
sub_sum=Sum('sub'),
).annotate(
total=F('add_sum')+F('sub_sum')
)
This will give you each date with fields representing add_sum, sub_sum, and total. If you wanted to aggregate all the totals of all dates then you'd want to do then:
print(resultado.aggregate(total_all=Sum('total'))['total_all'])
Django and HTML template : Group by panels with common object attributes
You should restructure your data in the view so that it's already prepared for the template. Django's template system is built in a way to avoid this type of logic.
You might be able to do it simply like this:
from collections import defaultdict
research_categories = defaultdict(list)
for element in test_research:
research_categories[element.publication.category].append(element)
Then use research_categories
in your template.
Using multiple model fields to regroup list in Django template
Your model function is correct but it should contain a %
before the braces:
def display_name(self):
return "%s, %s" %(self.name, self.city)
Your view should pass a list of objects and not values.
Let the list be tp
, so your template code should be something like this:
{% regroup tp by display_name as tp_list %}
<ul>
{% for t in tp_list %}
<li>{{ t.grouper }}
<ul>
{% for item in t.list %}
<...something of your code....>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
This should work out for you well enough.
Django read 3 variables at once from list
Django templates let you check 'where you are' in the for loop, so all you have to do is open and close your rows appropriately:
{% for user in user_list %}
{% if forloop.counter0|divisibleby:"3" %}<div class="row">{% endif %}
<div class="col align-self-center">
<form> <button class="btn btn-outline-primary btn-sm btn-block" formaction="{% url 'interface:data' user.id %}">{{user.id}}</button> </form>
{% if forloop.last or forloop.counter|divisibleby:"3" %}</div>{% endif %}
{% endfor %}
Related Topics
Css: on Hover Show and Hide Different Div's at the Same Time
Google Chrome > Textboxes > Yellow Border When Active..
How to Change the Link Color in a Specific Class for a Div CSS
In What Circumstances Is Flex-Shrink Applied to Flex Elements and How Does It Work
Stop Firefox Dpi Scaling (When Windows Setting Is at 125%)
Row Wrap in Flex-Box Not Wrapping in Safari
CSS List Item Width/Height Does Not Work
Ie - Hidden Radio Button Not Checked When the Corresponding Label Is Clicked
Custom CSS Being Overridden by Bootstrap CSS
How to Match 3D Perspective of Real Photo and Object in CSS3 3D Transforms
How to Target Safari for MAC Only
Set Bootstrap Navbar Transparency on Scroll
Using Vim, How to Make CSS Rules into One Liners
How to Make Circular Background Using CSS
Image Moves on Hover When Changing Filter in Chrome
Differencebetween Background-Size: Cover; and Background-Size: 100%;