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 ><a href="{{ category.get_absolute_url }}"><span >{{ post.category}}</span></a></div>
<h1 >
{{ 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!
CodePudding user response:
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 ><a href="{{ category.get_absolute_url }}"><span >{{ post.category}}</span></a></div>
<h1 >
{{ post.post_title }}
</h1>
CodePudding user response:
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.