Precautions when creating a view that narrows down records by date and time

I will do it every time, so as a memo for myself. I'm disappointed because I couldn't come up with a suitable title. ..

When implementing news articles in Django, I think that it is common to set fields such as publication date and time and expiration date and switch between public and private compared to the current date and time, but as follows It is not good to write in.

from django.db import models
from django.utils import timezone


class ArticleManager(models.Manager):
    def published(self):
        qs = self.get_queryset()
        return qs.filter(published_at__lte=timezone.now())


class Article(models.Model):
    title = models.CharField('title', max_length=100)
    published_at = models.DateTimeField('Publication date and time', default=timezone.now)

    objects = ArticleManager()


class ArticleView(ListView):
    queryset = Article.objects.published()  #This is no good
    # queryset = Article.objects.filter(published_at__lte=timezone.now())  #Of course this is also useless

Reasons not good

If you think about it for a moment, you can see that the queryset specified in ʻArticleView is a class variable, so the class is read and the value is determined when the server starts. ʻArticle.objects.published () works on the date and time when this process was executed, so in the above case it works like the time when the server started is the current time.

solution

What I want to do is I want to judge whether it is public or private based on the requested date and time, so if you do the following, it will work correctly.

from django.db import models
from django.utils import timezone


class ArticleManager(models.Manager):
    def published(self):
        qs = self.get_queryset()
        return qs.filter(published_at=timezone.now())


class Article(models.Model):
    title = models.CharField('title', max_length=100)
    published_at = models.DateTimeField('Publication date and time', default=timezone.now)

    objects = ArticleManager()


class ArticleView(ListView):
    queryset = Article.objects.all()

    #Works on every request
    def get_queryset(self):
        qs = super(ArticleView, self).get_queryset()
        return qs.published()

Summary

It's nothing more than just a careless mistake, but I'm addicted to it without noticing anything else (maybe just me !!), so please be careful.

Recommended Posts

Precautions when creating a view that narrows down records by date and time
Precautions when creating a Python generator
[Python] Rename all image files in a specific folder by shooting date and time
Creating a list when the nomenclature is a fixed time
A shell script that numbers duplicate names when creating files
[Python] Create a date and time list for a specified period