Home > other >  How to use two separate block tags on the same template
How to use two separate block tags on the same template

Time:06-15

I am trying to create a template for a blog landing page. Basically, I am trying to extend certain features from my base template, so I have two block tags that I want to appear at different parts of the page. Here is the first block tag;

{% extends 'index.html' %}
{% block content %}
{% for politic in politics %}
<div >
    <a href="single-post.html"><img src="{{politic.image.url}}" alt="" ></a>
    <div >
        <span >{{politic.category}}</span> 
        <span >&bullet;</span> 
        <span>{{politic.created_at}}</span>
    </div>
    <h2 ><a href="single-politic.html">{{politic.title}}</a></h2>
    <span >Ole Pundit</span>
    <p >{{politic.body|truncatewords:75}}</p>
</div>
{% endfor %}
{% endblock %}

But once the number of blog posts uploaded (politics.count) reaches 4, I want the for loop in the first block tag to break. And the following block tag to be executed;

{% block sidepolitics %}
{% if politics.count > 4 %}
{% for politic in politics %}
    <div >
        <div >
            <span >{{politic.category}}</span>
            <span >&bullet;</span> 
            <span>{{politic.created_at}}</span>
        </div>
        <h2 >
            <a href="single-post.html">{{politic.title}}

            </a>
        </h2>
        <span >Ole Pundit</span>
    </div>
{% endfor %}   
{% endif %}
{% endblock %}

Meaning the maximum number of blogposts that should follow the first layout is four, and the rest should all follow the second layout.

Both blog tags are nested under the political.html file below

{% extends 'index.html' %}
{% block content %}
{% for politic in politics %}
<div >
    <a href="single-post.html"><img src="{{politic.image.url}}" alt="" ></a>
    <div >
        <span >{{politic.category}}</span> 
        <span >&bullet;</span> 
        <span>{{politic.created_at}}</span>
    </div>
    <h2 ><a href="single-politic.html">{{politic.title}}</a></h2>
    <span >Ole Pundit</span>
    <p >{{politic.body|truncatewords:75}}</p>
</div>
{% endfor %}
{% endblock %}
{% block sidepolitics %}
{% if politics.count > 4 %}
{% for politic in politics %}
    <div >
        <div >
            <span >{{politic.category}}</span>
            <span >&bullet;</span> 
            <span>{{politic.created_at}}</span>
        </div>
        <h2 >
            <a href="single-post.html">{{politic.title}}

            </a>
        </h2>
        <span >Ole Pundit</span>
    </div>
{% endfor %}   
{% endif %}
{% endblock %}

And here is my base template **index.html;

 <div >
          {% block content %}
          {% endblock %}
          </div>
        </div>
         
        <div >
          {% block sidepolitics %}
          {% endblock %}
        </div>

**view.py

from django.shortcuts import render
from .models import Post, Politics
from django.views.generic import DetailView

# Create your views here.

def index(request):
    return render(request, 'index.html')

def allposts(request):
    posts = Post.objects.all()
    return render(request, 'allposts.html', {'posts':posts})

def political(request):
    politics = Politics.objects.all()
    return render(request, 'political.html', {'politics':politics})

def post(request, pk):
    posts = Post.objects.get(id=pk)
    return render(request, 'posts.html', {'posts':posts})  

The problem is, for both for loops the application starts iterating from the very beginning. How can I make the first for loop to iterate only up to the fourth count, and the second for loop to pick up right where the first loop leaves off.

CodePudding user response:

Firstfully, if you want to count objects, you need to use .count in template:

{% if politics > 4 %}         # good for integers or similar
{% if politics.count > 4 %}   # good for querysets

Secondly, you need to understand standard pythonish for loops because {% for politics in politics %} just makes absolutely no sense. It works like this:

{% for politic in politics %}    # usually it's like this: {% for SINGULAR in PLURAL %}

otherwise you are overriding politics variable and it should not work, at least not good.

Second loop makes no sense at all, I guess you don't need it.

With that said and your edits, use forloop.counter. It returns int with the current loop round. Here's hint:

{% for item in item_list %}
    {{ forloop.counter }} # starting index 1
    {{ forloop.counter0 }} # starting index 0
{% endfor %}

Instead of {% if politics.count > 4 %} that now I understand you don't need, use above logic. In first loop:

{% for politic in politics %}
    {% if forloop.counter < 5 %}
        # whole first for loop here
    {% else %}
        # whole second for loop here
    {% endif %}
{% endfor %}
  • Related