Reputation: 191
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
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
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">« 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 »</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
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
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
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
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