Django подсчет категорий, печать не может быть отфильтрована

я хочу решить проблему с категориями в django

я хочу распечатать, считая как данные категории.

например

  • python (3)

  • html (2)

но результат

как я могу решить? Я пришлю свои коды

# models.py

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

import os

class Category(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=200, unique=True, allow_unicode=True)

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return f"/blog/category/{self.slug}/"
    

    # admin 단에서의 이름을 설정
    class Meta:
        verbose_name_plural = "categories"


class Post(models.Model):
    title = models.CharField(max_length=30)
    # 후킹해주는 메세지 100글자 한도로 노출
    hook_text = models.CharField(max_length=100, blank=True)
    content = models.TextField()

    # auto_now=True를 해주면, 추가로 입력해줄 것 없이, 해당되는 내용이 자동 등록 된다.
    # settings에 MEDIA_URL, MEDIA_ROOT로 넣어주었던 주소 뒤로 어떻게 해줄지를 말해준다.
    head_image = models.ImageField(upload_to="blog/images/%Y/%m/%d/", blank=True)
    file_upload = models.FileField(upload_to="blog/files/%Y/%m/%d/", blank=True)

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    # CASCADE는 연결되어있는 값도 같이 삭제 해준다는 뜻
    # SET_NULL은 해당 값을 삭제해도, 해당 pk 값은 공백으로 두되, 나머지 데이터는 살려두는 것
    # blank=True를 해줘야 카테고리 미 추가시 오류가 뜨지 않는다.
    author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)
    category = models.ForeignKey(Category, null=True, blank=True, on_delete=models.SET_NULL)
    tags = models.ManyToManyField(Tag, blank=True)

    # 이걸로써, 관리자 단에서 내용을 보게 되면 작성된 텍스트로 표시된다.
    def __str__(self):
        return f"[{self.pk}]{self.title} :: {self.author}"

    def get_absolute_url(self):
        return f"/blog/{self.pk}/"

    def get_file_name(self):
        return os.path.basename(self.file_upload.name)
    
    def get_file_ext(self):
        return self.get_file_name().split(".")[-1]
# urls.py

from django.urls import path
from . import views

urlpatterns = [
    # path("", views.index),
    path("", views.PostList.as_view()),
    # path("<int:pk>/", views.single_post_page),
    path("<int:pk>/", views.PostDetail.as_view()),
    path("category/<str:slug>/", views.category_page),
    path("tag/<str:slug>/", views.tag_page),
    path("create_post/", views.PostCreate.as_view())
]
# views.py

from django.shortcuts import render, redirect
from django.views.generic import ListView, DetailView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .models import Post, Category

class PostList(ListView):
    model = Post
    ordering = "-pk"
    # template_name = "blog/index.html"

    def get_context_data(self, **kwargs):
        context = super(PostList, self).get_context_data()
        context["categories"] = Category.objects.all()
        context["no_category_post_count"] = Post.objects.filter(category=None).count()
        # context["category"] = None
        return context
        

class PostDetail(DetailView):
    model = Post

    def get_context_data(self, **kwargs):
        context = super(PostDetail, self).get_context_data()
        context["categories"] = Category.objects.all()
        context["no_category_post_count"] = Post.objects.filter(category=None).count()
        return context

class PostCreate(LoginRequiredMixin, CreateView):
    model = Post
    fields = ["title", "hook_text", "content", "head_image", "file_upload", "category"]

    def form_valid(self, form):
        current_user = self.request.user
        if current_user.is_authenticated:
            form.instance.author = current_user
            return super(PostCreate, self).form_valid(form)
        else:
            return redirect("/blog/")
      


def category_page(request, slug):
    if slug == "no_category":
        category = None
        post_list = Post.objects.filter(category=None)
    else:
        category = Category.objects.get(slug=slug)
        post_list = Post.objects.filter(category=category)

    return render(
        request,
        "blog/post_list.html",
        {
            "post_list": post_list,
            "categories": Category.objects.all(),
            "no_category_post_count": Post.objects.filter(category=None).count(),
            "category": category
        }
    )
  1. я пробовал общаться в чате gpt - но не получилось.

  2. я попробовал объединить части категории - но не получилось

Вы можете использовать метод annotate() вместе с функцией агрегирования Count из Django ORM, чтобы найти и сохранить количество объектов, хранящихся в QuerySet.

from django.db.models import Count
...
"categories": Category.objects.annotate(post_count=Count('post')),

Count('post') объединяет количество объектов Post, связанных с каждой категорией через ForeignKey. Затем вы можете ссылаться на свою собственную аннотацию, post_count, в своих шаблонах:

<ul>
    {% for category in categories %}
        <li>
            <a href="{{ category.get_absolute_url }}">{{ category.name }}</a>
            ({{ category.post_count }} posts)
        </li>
    {% endfor %}
</ul>

Не беспокойтесь о замене метода all(), разницы нет - В чем разница между objects.all().annotate и objects.annotate?

Вернуться на верх