I'm working on my blog. I'm trying to list my latest posts in page list_posts.html.I tried but posts are not shown, I don't know why. I don't get any errors or anything, any idea why my posts aren't listed?
This is models.py
from django.db import models
from django.utils import timezone
from ckeditor.fields import RichTextField
from stdimage import StdImageField
STATUS = (
(0,"Publish"),
(1,"Draft"),
)
class Category(models.Model):
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
title = models.CharField(max_length=255, verbose_name="Title")
class Meta:
verbose_name = "Category"
verbose_name_plural = "Categories"
ordering = ['title']
def __str__(self):
return self.title
class Post(models.Model):
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at")
updated_at = models.DateTimeField(auto_now=True, verbose_name="Updated at")
is_published = models.BooleanField(default=False, verbose_name="Is published?")
published_at = models.DateTimeField(null=True, blank=True, editable=False, verbose_name="Published at")
title = models.CharField(max_length=200, verbose_name="Title")
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey('auth.User', verbose_name="Author", on_delete=models.CASCADE)
category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE)
body = RichTextField(blank=True, null=True)
image = StdImageField(upload_to='featured_image/%Y/%m/%d/', variations={'standard':(1170,820),'banner':(1170,530),'thumbnail':(500,500)})
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
verbose_name = "Post"
verbose_name_plural = "Posts"
ordering = ['-created_at']
def publish(self):
self.is_published = True
self.published_at = timezone.now()
self.save()
def __str__(self):
return self.title
This is views.py
from django.shortcuts import render, get_object_or_404
from django.utils import timezone
from .models import Category, Post
def post_list(request):
posts = Post.objects.filter(published_at__lte=timezone.now()).order_by('published_at')
latest_posts = Post.objects.filter(published_at__lte=timezone.now()).order_by('published_at')[:5]
context = {'posts': posts, 'latest_posts': latest_posts}
return render(request, 'list_posts.html', context)
def post_detail(request, pk, post):
latest_posts = Post.objects.filter(published_at__lte=timezone.now()).order_by('published_at')[:5]
post = get_object_or_404(Post, pk=pk)
context = {'post': post, 'latest_posts': latest_posts}
return render(request, 'post_detail.html', context)
This is list_posts.html
{% extends "base.html" %}
{% load static %}
{% block content %}
<!-- Main Wrap Start -->
<main >
<div >
{% for post in latest_posts %}
<div >
<div >
<div >
<span ><i ></i></span>
<a href="{{ post.get_absolute_url }}">
<img src="{{ post.image.standard.url }}" alt="post-slider">
</a>
</div>
<h6 >
<a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
</h6>
<div >
<span >By <a href="#">{{ post.author }}</a></span>
<span >{{ post.created_at}}</span>
</div>
</div>
</div>
{% endfor %}
</div>
</main>
{% endblock content%}
Everything works except that posts aren't listed. Why I don't get listed posts?
Thanks in advance!
CodePudding user response:
The reason this doesn't work is because the published_at
is apparently NULL
and is thus never filled in. With the .filter(published_at__lte=timezone.now())
, it checks that the published_at
is less than or equal to the current timestamp. If it is NULL
, it thus is excluded. That means that you will either need to fill in the published_at
some way, or filter (and order) with a different field, like created_at
. You can thus work with:
from django.db.models.functions import Now
from django.shortcuts import get_object_or_404, render
from .models import Category, Post
def post_list(request):
posts = Post.objects.filter(created_at__lte=Now()).order_by('-created_at')
latest_posts = posts[:5]
context = {'posts': posts, 'latest_posts': latest_posts}
return render(request, 'list_posts.html', context)
def post_detail(request, pk, post):
latest_posts = Post.objects.filter(created_at__lte=Now()).order_by(
'-created_at'
)[:5]
post = get_object_or_404(Post, pk=pk)
context = {'post': post, 'latest_posts': latest_posts}
return render(request, 'post_detail.html', context)
Note: You can work with
Now
[Django-doc] to work with the database timestamp instead. This can be useful if you want to specify thequeryset
in a class-based view, since each time the queryset is evaluated, it will then take the (updated) timestamp.