Answer the question
In order to leave comments, you need to log in
How to select posts by status?
Good day!
I'm trying to write a hackneyed blog application.
There are two tables in the model: rubric and posts.
Both tables have a status: draft and published.
There is not enough knowledge to make a selection according to the status published from both tables.
Now the selection is made only by the status "published" from the posts table.
#models.py
from django.db import models
from django.utils import timezone
from django.conf import settings
from django.urls import reverse
class PublishedManager(models.Manager):
def get_queryset(self):
return super(PublishedManager, self).get_queryset()\
.filter(status='published')
class CommonInfo(models.Model):
'Абстрактная модель для общих полей'
STATUS_CHOICES = (
('draft', 'Черновик'),
('published', 'Опубликовано'),
)
title = models.CharField(max_length=200, verbose_name='Заголовок')
description = models.CharField(max_length=160, blank=True, null=True, verbose_name='Краткое описание')
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft', verbose_name='Статус')
objects = models.Manager()
published = PublishedManager()
class Meta:
abstract = True
class Rubric(CommonInfo):
class Meta:
verbose_name = 'Рубрика'
verbose_name_plural = 'Рубрики'
def __str__(self):
return self.title
class Post(CommonInfo):
cover = models.ImageField(upload_to='cover', height_field=600, width_field=600, max_length=200, blank=True, null=True, verbose_name='Обложка')
rubric = models.ForeignKey(Rubric, on_delete=models.CASCADE, verbose_name='Рубрика')
slug = models.CharField(max_length=200, unique=True, verbose_name='url статьи')
body = models.TextField(blank=True, null=True, verbose_name='Текст')
keywords = models.CharField(max_length=255, blank=True, null=True, verbose_name='Ключевые слова')
create_date = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
publish = models.DateTimeField(default=timezone.now, verbose_name='Дата публикации')
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='blog_posts', verbose_name='Автор')
def get_absolute_url(self):
return reverse('blog:post_detail', args=[self.slug])
def get_rubric_status(self):
return self.rubric.status
class Meta:
verbose_name = 'Статья'
verbose_name_plural = 'Статьи'
def __str__(self):
return self.title
#view.py
from django.shortcuts import render
from django.views import generic
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from .models import Post
import pdb
class ListView(generic.ListView):
queryset = Post.published.all()
# queryset = Post.published.all().model.rubric.get_queryset().filter(status='published')
template_name = 'blog/blog_list.html'
context_object_name = 'posts'
paginate_by = 3
pdb.set_trace()
class DetailView(generic.DetailView):
model = Post
template_name = 'blog/blog_detail.html'
context_object_name = 'post_detail'
Answer the question
In order to leave comments, you need to log in
At the moment I found such a solution.
Changed the
line in view.py
to
I hope this is the right decision. At least the result is what I expected.
To sort by a field from another model, use the same syntax as when filtering by fields in a related model. That is, the name of the field, followed by two underscores (__), and the name of the field in the new model, and so on. For example:
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question