如何在Django中列出最新的文章?

3

我正在编写我的博客,尝试在页面list_posts.html中列出我的最新文章。但是我尝试过后文章并没有显示出来,我不知道为什么。我没有收到任何错误信息,有什么想法吗?

这是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

这是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)

这是list_posts.html文件

{% extends "base.html" %}
{% load static %} 
        {% block content %}
        <!-- Main Wrap Start -->
        <main class="position-relative">
            <div class="post-carausel-1-items mb-50">
                {% for post in latest_posts %}
                <div class="col">
                    <div class="slider-single bg-white p-10 border-radius-15">
                        <div class="img-hover-scale border-radius-10">
                            <span class="top-right-icon bg-dark"><i class="mdi mdi-flash-on"></i></span>
                            <a href="{{ post.get_absolute_url }}">
                                <img class="border-radius-10" src="{{ post.image.standard.url }}" alt="post-slider">
                            </a>
                        </div>
                        <h6 class="post-title pr-5 pl-5 mb-10 mt-15 text-limit-2-row">
                            <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
                        </h6>
                        <div class="entry-meta meta-1 font-x-small color-grey float-left text-uppercase pl-5 pb-15">
                            <span class="post-by">By <a href="#">{{ post.author }}</a></span>
                            <span class="post-on">{{ post.created_at}}</span>
                        </div>
                    </div>
                </div>
                {% endfor %}
            </div>
        </main>
        {% endblock content%}

除了文章未被列出之外,一切都正常。为什么我的文章没有被列出?

先行致谢!


published_at 的值已经填充了吗?你能检查一下数据库吗? - Willem Van Onsem
published_at 是空的。 - Firefoxer
1
既然你使用了.filter(published_at__lte=timezone.now()),那么它将会过滤掉所有的文章,因此返回一个空的查询集。 - Willem Van Onsem
啊,谢谢...我使用了 created_at ,现在可以正常工作了。非常感谢。 - Firefoxer
1
由于您正在按递减的方式排序,我建议将 published_at__lte=timezone.now() 更改为 published_at__isnull=False。如果 published_at 为空,则看起来您没有调用 .publish() 方法。 - JoVi
1个回答

2
这个代码不起作用的原因是因为published_at显然是NULL,因此从未被填充。使用.filter(published_at__lte=timezone.now())时,它会检查published_at是否小于或等于当前时间戳。如果它是NULL,那么就会被排除在外。这意味着您需要以某种方式填写published_at,或者使用不同的字段进行筛选(和排序),例如created_at。因此,您可以尝试以下方法:
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)

注意: 您可以使用Now [Django-doc]来处理数据库时间戳。如果您想在基于类的视图中指定queryset,这将非常有用,因为每次评估queryset时,它都会采取(更新后的)时间戳。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接