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>
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)
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 toNewsView
, instead of.news
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.