Home > Software design >  How to get the previous and next related post in django?
How to get the previous and next related post in django?

Time:07-31

views.py

def post_details(request,pk):
    post = Post.objects.get(id=pk)
    # next_post = Post.objects.filter(id=pk)
    context={'post':post,'next':next_post}
    return render(request, 'blog/post_detail.html', context)

blog-detail

<div >
    <div >
        <a href="#" rel="prev">
            <span>Previous</span>
            Tips on Minimalist Design 
        </a>
    </div>
    
     <div >
         <a href="#" rel="next">
             <span>Next</span>
            Less Is More 
         </a>
     </div>

</div> 

models
#this is my model class User(AbstractUser): # pass name = models.CharField(max_length=200) bio = models.TextField(null=True) email = models.EmailField(unique=True, null=True) avatar = models.ImageField( null=True, upload_to='blog_media', default="images/avatar.svg") facebook = models.URLField(blank=True, null=True) twitter = models.URLField(blank=True, null=True) dribbble = models.URLField(blank=True, null=True) instagram = models.URLField(blank=True, null=True)

class Category(models.Model):
    name = models.CharField(max_length=20)
    
    class Meta:
        verbose_name = 'Category'
        verbose_name_plural = 'Categories'
    def __str__(self):
        return self.name

    class Post(models.Model):
        author = models.ForeignKey(User, on_delete=models.CASCADE)
        category = models.ManyToManyField(Category)
        title = models.CharField(max_length=200, blank=False);
        description = models.TextField(null=True,blank=True)
        image = models.ImageField(upload_to='blog_media') 
        url = models.URLField(null=True, blank=True)
        body = HTMLField()
        created = models.DateTimeField(auto_now=True)
        updated = models.DateTimeField(auto_now_add=True)
        def __str__(self):
            return self.title
    
    

CodePudding user response:

Based on your comments, I'm assuming that you would like to get two related posts that have the same category as the current post.

If I'm correct, then one method you could use is to filter the queryset for the same category belonging to the current post then you could choose the next and previous posts of the current post from the retrieved queryset. For example:

def post_details(request, pk):
     current_post = Post.objects.get(pk=pk) # retrieving the current post...
   
     # filtering for related posts only by using the category of the current post
     # using -> category_in=post.category.all() since it's a ManyToMany field
     related_posts = Post.objects.filter(category_in=current_post.category.all())

     # next -> get posts with id greater than the current post id, then get the first instance 'next post'
     # previous -> get posts with id less than the current post id, then get the first instance 'previous post'
     context = {
          'post': current_post,
          'next': related_posts.filter(id__gt=current_post.id).order_by('id').first(), 
          'previous': related_posts.filter(id__lt=current_post.id).order_by('-id').first()
     }

     return render(request, 'blog/post_detail.html', context)

Ideally, that should work.

A quick recommendation here as well... Instead of using Post.objects.get(pk=pk), I'd suggest using get_object_or_404() as this will handle any potential error that Post.objects.get(pk=pk) will throw. So a small update...

from django.shortcuts import get_object_or_404

def post_details(request, pk):
     current_post = get_object_or_404(Post, pk=pk) # retrieving the current post...

     # the rest of the code follows...
  • Related