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
}
)
я пробовал общаться в чате gpt - но не получилось.
я попробовал объединить части категории - но не получилось
Вы можете использовать метод 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?