Paulo Soares
Paulo Soares

Reputation: 177

"Next" and "Previous" button on Django, on posts with Slugs

What I want is to create "Next Post" and "Previous Post" on Django. What I have managed to do until now is to link the button to a page where the primary key is one above or one below the current post:

<a class="btn btn-default" href="{% url 'post_detail' slug=post.slug pk=post.pk|add:'1' %}">Next</a>

There are two issues: one is with the Slug and with the URL, and the other is with the showing (or hiding) of the button.

When I click next, I am taken to the next post (if it exists. If it doens't I receive an error telling me that such a page doesn't exist). The URL remains the same as the previous post, correspondingly: If I click it three times, the URL displayed will be the one of the second post. What I would like is to somehow also display the corresponding slug.

The second problem, is that I want to disable the button if there is no post before or after. But the following piece of code:

  {% if post.pk|add:'1' %}

Which is what I have come up with up until now. But apparently it checks if such a number exists, not if the post exists or not.

The view class for this page is the following:

class PostDetailView(HitCountDetailView):
    model = Post
    slug_field = "title"
    count_hit = True

Whereas the model is (removing irrelevant-to-this-issue code):

@python_2_unicode_compatible
class Post(models.Model, HitCountMixin):
    author = models.ForeignKey('auth.User')
    title = models.CharField(max_length=100, null=False, blank=False)
    text = models.TextField(null=False, blank=False)
    slug = models.SlugField(max_length=100, blank=True)

    # rewrite save method
    def save(self, *args, **kwargs):
        if not self.id:
            self.slug = slugify(self.title)
        super(Post, self).save(*args, **kwargs)

    def article_pre_save(signal, instance, sender, **kwargs):
        instance.slug = slugify(instance.title)

    signals.pre_save.connect(article_pre_save, sender="blog.Post")

    # go to post page 
    def get_absolute_url(self):
        return reverse("post_detail", kwargs={'slug':self.slug, 'pk':self.pk})

    # retorna o título do post
    def __str__(self):
        return self.title

And the related url:

    url(_(r'^post/(?P<pk>\d+)-(?P<slug>[-\w]+)/$'), views.PostDetailView.as_view(), name='post_detail'),

How could I proceed to this? I thought about writing a Raw SQL query (I've been having problems with this too, but that's another matter), but I don't know, up to now, how I could actually link it to the template. Thank you for your help, if you will, and attention, in advance.

Upvotes: 1

Views: 3022

Answers (1)

Nakul Narayanan
Nakul Narayanan

Reputation: 1452

django-next-prev refer this. its good package for these kinds of requirements. this package will get you the next and previous object of the current object. after that, you have to build the next and previous URL using reverse or reverze_lazy methods in Django

Upvotes: 4

Related Questions