Jieke Wei
Jieke Wei

Reputation: 183

Django - inclusion tag

In my html, there is a div containing all the comments. I need to restrict the amount of comments to be shown. So, I created an inclusion tag:

<div class="past_comments">
    {% limit_amount_in_a_page page_nr=page_nr topic_id=topic.id amount=4 %}
</div>

@register.inclusion_tag('post/comment_block.html')
def limit_amount_in_a_page(page_nr, topic_id=1, amount=5):
    topic = get_object_or_404(Topic, id=topic_id)
    comments = Comment.objects.filter(topic=topic)
    selected_comments = []
    starting_index = page_nr*amount
    for index in range(starting_index, starting_index + amount):
        if index >= len(comments):
            break;
        selected_comments.append(comments[index])
    return {
        'topic': topic,
        'page_nr': int(page_nr),
        'selected_comments': selected_comments,
        'amount_comments': comments.all().count(),
        'limit_amount_comment': amount,
    }

so, this tag shows the code from comment_block.html

{% load static %}
{% load post_tags %}
{% load post_filters %}
{% for comment in selected_comments %}
    <div class="comment_body">
    <div class="user_info_block">
        <div class="content">
            <div class="photo_profile"></div>
            <div class="user_info"></div>
        </div>
    </div>
    <div class="content_block">

        <p>{{comment.content}}</p>
    </div>
    </div>
{% endfor %}
topic id is {{topic.id}}
page nr is {{page_nr}}<br>
comment amount is {{amount_comments}}<br>
limit amount is {{limit_amount_comment}}<br>
{% if page_nr != 0 %}
    <a href="{% url 'post:detail' topic.id page_nr|increase:-1 %}">Previous Page</a>
{% endif %}

{%page_not_over_amount page_nr amount_comments limit_amount_comment%}

{% if  comment_not_over_amount %}
    <a href="{% url 'post:detail' topic.id page_nr|increase:1 %}">Next Page</a>
{% endif %}

As you can see, I created another tag page_not_over_amount after all comments are shown to hide the link directing to the next page if all comment already been shown

@register.inclusion_tag('post/comment_block.html')
def page_not_over_amount(page_nr, comment_amount, comment_limit):
    result = page_nr * comment_limit < comment_amount - comment_limit
    return {'comment_not_over_amount': result}

However, I found my tag page_not_over_amount didn't ready any variable from the comment_block.html (After I get the exception, I checked the local variables. All their values are ""). I guess the possible cause of this is both tags are redirecting to the same html file. After the second tag redirects, it refreshs all the variables in the page.

Should I call a context variable?

Upvotes: 0

Views: 1086

Answers (1)

Sam Bobel
Sam Bobel

Reputation: 1824

Okay, so it seems like you're going for a basic pagination scheme. First things first, you should look at the built-in solution in Django. You should definitely take an hour and try and make that work.

Django's a heavyweight framework that has a built-in way of doing most things, and libraries for everything else. As a general rule, if you find yourself doing a common task in a convoluted way, there's probably a stock solution out there.

If you decide you want to do it the quick and dirty way, how about calculating has_next_page and has_prev_page in limit_amount_in_a_page?

@register.inclusion_tag('post/comment_block.html')
def limit_amount_in_a_page(page_nr, topic_id=1, amount=5):
    topic = get_object_or_404(Topic, id=topic_id)
    comments = Comment.objects.filter(topic=topic)
    num_comments = comments.count()
    selected_comments = comments[page_nr*amount, (page_nr + 1)*amount]
    has_prev = (page_nr != 0)
    has_next = ((page_nr + 1) * amount) < num_comments
    return {
        'topic': topic,
        'page_nr': int(page_nr),
        'selected_comments': selected_comments,
        'has_next' : has_next,
        'has_prev' : has_prev,
        'amount_comments' : num_comments,
    }

Also, note the use of slices to select comments.

But again, I highly recommend checking out the Paginator class in Django. Reading through the docs and doing the tutorial is a great thing to do as well, if you have not yet. Skimming through all the docs gives you an idea of what is built-in, which saves a lot of time in the long run.

Upvotes: 3

Related Questions