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 Post
s with status=1
(so published Post
objects).