Home > Enterprise >  Django limit next post and previos post on Detail view to only active
Django limit next post and previos post on Detail view to only active

Time:10-28

I currently have a model view as such

from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone

STATUS = (
    (0,"Draft"),
    (1,"Publish")
)


class Post(models.Model):
    title = models.CharField(max_length=200, unique=True)
    slug = models.SlugField(max_length=200, unique=True)
    author = models.ForeignKey(
        User, on_delete=models.CASCADE, related_name="blog_posts"
    )
    updated_on = models.DateTimeField(auto_now=True)
    content = models.TextField()
    created_on = models.DateTimeField(auto_now_add=True)
    status = models.IntegerField(choices=STATUS, default=0)

    class Meta:
        ordering = ["-created_on"]

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        from django.urls import reverse

        return reverse("post_detail", kwargs={"slug": str(self.slug)})

and my view looks like so

class PostDetail(DetailView):
    model = Post
    template_name = 'post_detail.html'

and my template looks like so

    <ul class="text-center">
        {% if post.get_previous_by_created_on_active %}
        <li class="prev">
            <a rel="next" href="{{ post.get_previous_by_created_on.get_absolute_url}}">
                {{ post.get_previous_by_created_on_active}}</a>
        </li>
        {% endif %}
        {% if post.get_next_by_created_on %}
        <li class="next">
            <a rel="next" href="{{ post.get_next_by_created_on.get_absolute_url}}">
                {{ post.get_next_by_created_on}}
            </a>
        </li>
    </ul>

Is there any way I can pass the status == 1 to the get_next_by_created_on so it always shows the next active post, not the next draft post?

CodePudding user response:

You can define two extra methods in the Post model to only retrieve active items with:

class Post(models.Model):
    # ⋮

    def get_previous_by_created_on_active(self):
        return self.get_previous_by_created_on(status=1)

    def get_next_by_created_on_active(self):
        return self.get_next_by_created_on(status=1)

This will thus only look for Posts with status=1 (so published Post objects).

  • Related