2

Good evening, I have a problem while learning Django. The point is that I am doing a training news site, and there is such an item as "public" - whether the news is published or not. And to display only published news, use "def get_queryset" But I need to display news only with public = True and by the date the news was created

views.py

class news(ListView):
model = Post
template_name = 'flatpages/new.html'
context_object_name = 'news'
# paginate_by = 6

ordering = '-data'

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['cate'] = Category.objects.all()
    return context

def get_queryset(self):
    return Post.objects.filter(public=True)

models.py

class Category(models.Model):
category_name = models.CharField(max_length=64, unique=True)
subscribers = models.ManyToManyField(User, blank=True, null=True)


class Meta:
    verbose_name = 'Категория'
    verbose_name_plural = 'Категории'

def __str__(self):
    return self.category_name

class Post(models.Model):
PostAuthor = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name='Автор поста')

PostNews = 'PN'
PostArticle = 'PA'

# «статья» или «новость»
POSITIONS = [
    (PostArticle, 'Статья'),
    (PostNews, 'Новость'),
]

postCategory = models.ManyToManyField(Category, verbose_name='Категория поста',  through='PostCategory')
title = models.CharField(max_length=50, verbose_name='Название')
positions = models.CharField(max_length=2, choices=POSITIONS, default=PostArticle, verbose_name='Тип поста')
category_id = models.ForeignKey(Category, verbose_name='Категория', null=True, on_delete=models.CASCADE, related_name='category_id')
data = models.DateTimeField(auto_now_add=True, verbose_name='Дата создания')
data_update = models.DateTimeField(auto_now=True, verbose_name='Дата редактирования')
photo = models.ImageField(upload_to='photos/%Y/%m/%d/', verbose_name='Фото', blank=True, default='/photos/def/1.jpg/')
previewName = models.CharField(max_length=128, verbose_name='Превью поста')
text = models.TextField(verbose_name='Текст поста')
rating = models.SmallIntegerField(default=0, verbose_name='Рейтинг')
public = models.BooleanField(default=True, verbose_name='Опубликовано')

def like(self):
    self.rating +=1
    self.save()

def dislike(self):
    self.rating -=1
    self.save()

def preview(self):
    return self.text[0:124] + '...'

def __str__(self):
    return self.title

class Meta:
    verbose_name = 'Пост'
    verbose_name_plural = 'Посты'

def get_absolute_url(self):
    return f'/news/{self.pk}'

html page

        <div class="col-md-8">
        {%for el in news%}
        <div class="card mb-3">
            <div class="card-header">
                Категории: {{el.category_id}}
            </div>
            <br>
            <div class="row g-0">
                <div class="col-md-4">
                    {%if el.photo%}
                    <img src="{{el.photo.url}}" alt="" width="275" class="mr-3">
                    {%endif%}
                </div>
                <div class="col-md-8">
                    <div class="card-body">
                        <h5 class="card-title"><a style="color: #000000;" href="{% url 'news_detail' el.id %}">{{ el.title|censor_filter }}</a></h5>
                        <p class="card-text">{{ el.text|censor_filter|truncatewords:150 }}</p> <a
                            href="{% url 'news_detail' el.id %}" class="btn btn-primary">Читать полную новость</a>
                    </div>
                </div>
                <br>
                <div
                        class="card-footer text-muted " style="text-align: right;">Рейтинг статьи: {{el.rating}}<br>
                    Дата публикации {{ el.data|date:'d M Y H:m' }}
                </div>
            </div>
        </div>
        {%endfor%}
    </div>

https://i.sstatic.net/BG56m.png

2
  • What do you mean with the date it was created? Should this only return news published on the current day, or the last three days for example? Commented Jun 17, 2021 at 17:36
  • So that he sorts by the date the news was created Commented Jun 17, 2021 at 17:39

1 Answer 1

2

If you override the get_queryset, Django will no longer order the queryset, since that is implemented in the basic implementation of the view. You should order in the .get_queryset method with:

class news(ListView):
    model = Post
    template_name = 'flatpages/new.html'
    context_object_name = 'news'
    # paginate_by = 6

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['cate'] = Category.objects.all()
        return context
    
    def get_queryset(self):
        #                          use order_by(…) ↓
        return Post.objects.filter(public=True).order_by('-data')

Note: In Django, class-based views (CBV) often have a …View suffix, to avoid a clash with the model names. Therefore you might consider renaming the view class to NewsView, instead of news.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.