Kaushik
Kaushik

Reputation: 191

Adding a maximum limit to the number of post using python

I need to limit the number of posts in Django queries. I have tried to add a min and max but nothing seemed to have worked. I have added home.html into the code.

Example: I should only have the 15 most recent posts in my blog. The rest can be seen by clicking on the category button.

Home.html:

{% extends 'base.html' %}

{% block content %}




<h1>Posts</h1>

<ul>
{% for post in object_list %}

    <li><a href="{% url 'article-detail' post.pk %}">{{post.title}}</a> 
<style>
    a {
        text-transform: capitalize;
    }
</style>
        - <a href="{% url 'category' post.category %}">{{ post.category }}</a> - <a href="{% url 'show_profile_page' post.author.profile.id %}">{{ post.author.first_name }} 
    {{ post.author.last_name }}</a> - {{ post.post_date }} <small>

        {% if user.is_authenticated %}
            {% if user.id == post.author.id %}

            - <a href="{% url 'update_post' post.pk %}">(Edit)</a>

            <a href="{% url 'delete_post' post.pk %}">(Delete)</a>
            {% elif user.id == 1 %}

            - <a href="{% url 'update_post' post.pk %}">(Edit)</a>

            <a href="{% url 'delete_post' post.pk %}">(Delete)</a>

            {% endif %}

        {% endif %}


    </small><br/>
    {{ post.snippet }}</li>
{% endfor %}
</ul>


{% endblock %}

view.py:

class HomeView(ListView):
    model = Post
    template_name = 'home.html'
    ordering = ['-id']

    def get_context_data(self, *args, **kwargs):
            cat_menu = Category.objects.all()
            context = super(HomeView, self).get_context_data(*args,**kwargs)
            context["cat_menu"] = cat_menu
            return context

models.py:

class Post(models.Model):
    title = models.CharField(max_length=255)
    header_image = models.ImageField(null=True, blank=True, upload_to='images/')
    title_tag = models.CharField(max_length=255)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    body = RichTextField(blank=True, null=True)
    post_date = models.DateField(auto_now_add=True)
    category = models.CharField(max_length=255, default='intro')
    snippet = models.CharField(max_length=255)
    likes = models.ManyToManyField(User, related_name='post_likes')
    dislikes = models.ManyToManyField(User, related_name='post_dislikes')

Upvotes: 3

Views: 1206

Answers (6)

Rasheed kotoor
Rasheed kotoor

Reputation: 329

I think you have another template for displaying categorised objects when you click category button. As you said

"I should only have the 15 most recent posts in my blog. The rest can be seen by clicking on the category button."

In this case you can use a simple hack to display most recent posts from your table. query all objects in descending order in views

    all_objs = Post.objects.all().order_by('-id')

Then use {% if forloop.counter <= 15 %} to display last 15 items only. as follow.

templates

{% for post in object_list %}

   {% if forloop.counter <= 15 %}

       <h4>{{obj}} #or anything really that is meant to be shown on the home page.</h4>

   {% endif %}

{% endfor %}

Upvotes: 5

xxxecute
xxxecute

Reputation: 190

https://docs.djangoproject.com/en/3.2/topics/pagination/

The best way is Django Pagintion.

{% for contact in page_obj %}
    {# Each "contact" is a Contact model object. #}
    {{ contact.full_name|upper }}<br>
    ...
{% endfor %}

<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>
from django.core.paginator import Paginator
from django.shortcuts import render

from myapp.models import Contact

def listing(request):
    contact_list = Contact.objects.all()
    paginator = Paginator(contact_list, 25) # Show 25 contacts per page.

    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, 'list.html', {'page_obj': page_obj})

Upvotes: 1

Rahul Hindocha
Rahul Hindocha

Reputation: 215

It is very simple. You just have to modify the query that you are using to fetch the posts.
In the get_context_data() method, replace cat_menu = Category.objects.all()
with cat_menu = Category.objects.all().order_by('-post_date')[:15]. This will limit the number of results to 15 most recent objects. For more understanding, you can take a look at the official Django docs for Limiting QuerySets.

Upvotes: 0

Badredine Kheddaoui
Badredine Kheddaoui

Reputation: 295

Just limit your query to the latest 15 entries sorted by post_date:

cat_menu = Category.objects.latest("post_date")[:15]

Upvotes: 1

Brian Destura
Brian Destura

Reputation: 12068

You can do something like this:

def get_context_data(self, *args, **kwargs):
    context = super(HomeView, self).get_context_data(*args,**kwargs)
    context["cat_menu"] = Category.objects.all()
    context["most_recent_posts"] = Post.objects.filter(author=self.request.user).order_by('-post_date')[:15]
    return context  

This will get the 15 most recent posts authored by the current user, ordered by the date it was posted.

Then just handle displaying this in home.html for example:

<ul>
{% for p in most_recent_posts %}
    <li>{{ p.title }}</li>
{% endfor %}
</ul>

Upvotes: 1

Pradeep Kumar
Pradeep Kumar

Reputation: 21

you can use Django pagination api . Manage your data through page number. Initially pass 1 and after that page number given by pagination.

 paginator = Paginator(yourquerysetdata, 20)
        page_num = request.data.get('page')
        result = yourSerializerName(paginator.get_page(page_num) many=True).data
        try:
            page = paginator.page(page_num)
        except:
            page = paginator.page(1)

        count = paginator.num_pages

        resultobj = paginator.get_page(page_num)
        has_prev = resultobj.has_previous()
        has_next = resultobj.has_next()
        page_range = resultobj.paginator.page_range.stop - 1
        if has_prev:
            prev_page_no = resultobj.previous_page_number()
        else:
            prev_page_no = 0

        if has_next:
            next_page_no = resultobj.next_page_number()
        else:
            next_page_no = None

        context = dict()
        context['page'] = page.number
        context['page_no'] = count

Upvotes: 0

Related Questions