Search code examples
pythondjangoblogs

Adding categories to a django blog


I made a simple django blog and I wanted it to display posts according to the category the post is assigned to. But it doesn't work as intended when I filtere it

enter image description here

instead of filtering the posts according to the category it shows the html code in the base.html file.

My polls/urls.py file

from django.urls import path

from .views import HomeView, ArticleDetailView, AddPostView, UpdatePostView
from .views import DeletePostView, AddCategoryView, CategoryView

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
    path('article/<int:pk>/', ArticleDetailView.as_view(), name='article-view'),
    path('add_post/', AddPostView.as_view(), name='add_post'),
    path('add_category/', AddCategoryView.as_view(), name='add_category'),
    path('article/edit/<int:pk>/', UpdatePostView.as_view(), name='update_post'),
    path('article/<int:pk>/remove/', DeletePostView.as_view(), name='delete_post'),
    path('category/<str:categories>/', CategoryView, name='category')
]

My views.py file

from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from .models import Post, Category
from .forms import PostForm, EditForm
from django.urls import reverse_lazy
from django.shortcuts import render


class HomeView(ListView):
    model = Post
    template_name = "home.html"
    # ordering = ["-post_date"]
    ordering = ["-id"]


class ArticleDetailView(DetailView):
    model = Post
    template_name = "detail_view.html"


class AddPostView(CreateView):
    model = Post
    form_class = PostForm
    template_name = "add_post.html"
    # fields = "__all__"


class AddCategoryView(CreateView):
    model = Category
    fields = "__all__"
    template_name = "add_category.html"


def CategoryView(request, categories):
    category_posts = Post.objects.filter(category=categories)
    return render(request, "categories.html", {"categories": categories}, {'category_posts': category_posts})


class UpdatePostView(UpdateView):
    model = Post
    form_class = EditForm
    template_name = "update_post.html"
    # fields = ("title", "title_tag", "body")


class DeletePostView(DeleteView):
    model = Post
    template_name = "delete_post.html"
    success_url = reverse_lazy("home")

My categories.html file

{% extends 'base.html' %}

{% block content %}
<head>
    <title>{{ categories }} category</title>
</head>

<h1>{{ categories }} category</h1>
<hr>

{% for post in category_posts %}
<ul>
    <li>
        <a href="{% url 'article-view' post.pk %}">
            {{ post.title }}</a> - 
        {{ post.category }} - 
        {{ post.author.first_name }}
        {{ post.author.last_name }} - {{ post.post_date }}<br/>
        <small>{{ post.body | slice:":359" | safe }}</small>

        {% if user.is_authenticated %}
        <small><a href="{% url 'update_post' post.pk %}"> (Edit) </a></small> <small><a
            href="{% url 'delete_post' post.pk %}">(Delete)</a></small> <br/>
        {% endif %}
    </li>
</ul>
{% endfor %}

{% endblock %}

My models.py file

from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse    

class Category(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return (self.name)

    def get_absolute_url(self):
        return reverse("home")


class Post(models.Model):
    title = models.CharField(max_length=255)
    title_tag = models.CharField(max_length=255)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    body = models.TextField(max_length=3500)
    post_date = models.DateField(auto_now_add=True)
    category = models.CharField(max_length=255, default="uncategorized")

    def __str__(self):
        return (self.title + " | " + str(self.author))

    def get_absolute_url(self):
        return reverse("home")

Thank you.


Solution

  • There is an error in your positional parameters in your return render() line. Context variables in your CategoryView should be in one dictionary.

    Replace

    {"categories": categories}, {'category_posts': category_posts}
    

    With

    {"categories": categories, 'category_posts': category_posts}