How to direct from post to category page in Django?

Question:

I’m working on my Django blog. I have a trouble to redirect from post to category, when you open post you can click to category and when you click on category I want you to redirect you to category and show posts only from that category.

This part of my html code for post_detail.html

<div class="entry-meta meta-0 font-small mb-30"><a href="{{ category.get_absolute_url }}"><span class="post-cat bg-success color-white">{{ post.category}}</span></a></div>
<h1 class="post-title mb-30">
    {{ post.post_title }}
</h1>

This is models.py only class category


class Category(models.Model):
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
    category_name = models.CharField(max_length=255, verbose_name="Category name")
    slug = models.SlugField(max_length=200, unique=True)

    def get_absolute_url(self):
        return reverse('category_detail', args=[self.slug])

    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"
        ordering = ['category_name']

    def __str__(self):
        return self.category_name

in post_detail is defined like this (short view)


class Post(models.Model):
    ...
    post_title = models.CharField(max_length=200, verbose_name="Title")
    category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE)
    ...

    def __str__(self):
        return self.post_title

This is views.py

def post_detail(request, slug):
    latest_posts =  Post.objects.filter(created_at__lte=timezone.now()).order_by('created_at')[:9]
    post = get_object_or_404(Post, slug=slug)

    context = {'post': post, 'latest_posts': latest_posts}
    return render(request, 'post_detail.html', context)


def category_detail(request, pk):
    category = get_object_or_404(Category, pk=pk)

    return render(request, 'category_detail.html', {'category': category})

This is urls.py

from . import views
from django.urls import path

urlpatterns = [
    path('', views.home, name='home'),
    path('<slug:slug>/', views.post_detail, name='post_detail'),
    path('<slug:slug>/', views.category_detail, name='category_detail'),
]

Any idea why I’m not redirected to category_detail page?

Thanks in advance!

Asked By: mdev

||

Answers:

Your problem lies here:

<a href="{{ category_detail.get_absolute_url }}">

Category_detail is the name of your view, not your the model instance (the thing that has the get_absolute_url method) that you passed to your view via Context. Try:

<a href="{{ category.get_absolute_url }}">

and you should have better luck.

Answered By: SamSparx

first of all edit your Post model and add related_name option to category field.

class Post(models.Model):
    ...
    post_title = models.CharField(max_length=200, verbose_name="Title")
    category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, related_name='posts')
    ...

    def __str__(self):
        return self.post_title

now in your category detail template you can access Posts related to that category:

in category_detail.html:

{% for post in category.posts.all %}
{{ post.post_title }}
{% endfor %}

and you need to edit your post_detail.html:
change {{ category.get_absolute_url }} to {{ post.category.get_absolute_url }}

<div class="entry-meta meta-0 font-small mb-30"><a href="{{ category.get_absolute_url }}"><span class="post-cat bg-success color-white">{{ post.category}}</span></a></div>
<h1 class="post-title mb-30">
    {{ post.post_title }}
</h1>
Answered By: amirhossein amiri
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.