naritoブログ

【お知らせ】
新ブログができました。今後そちらで更新し、このサイトは更新されません(ウェブサイト自体は残しておきます)
このブログの内容に関してコメントしたい場合は、新ブログのフリースペースに書き込んでください

このブログの内容を新ブログに移行中です。このブログで見つからない記事は、新ブログにありま

Djangoで、記事を公開順に表示する

約320日前 2017年12月29日4:00
プログラミング関連
Django Python
例えば、以下のようなモデルがあったとします。
タイトル、本文、作成日、そして、公開フラグを持ったモデルです。
ブログの記事には下書きという状態があり、本公開したい場合に、is_publicをTrueにすることにします。

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


class Post(models.Model):
"""ブログの記事"""

title = models.CharField('タイトル', max_length=255)
text = models.TextField('本文')
is_publick = models.BooleanField('公開フラグ', default=False)
created_at = models.DateTimeField('作成日', default=timezone.now)

def __str__(self):
return self.title



views.pyでの一覧表示は、以下のようになります。
単純にfilterで、公開フラグがTrueのものだけ取得します。

from django.views import generic
from .models import Post


class IndexView(generic.ListView):
model = Post

def get_queryset(self):
# 公開フラグがTrueで、作成日順に並び替え
return super().get_queryset().filter(is_publick=True).order_by('-created_at')





では本題です。現在は作成日順に並び替えていますが、これを記事の公開日順にしたいとすると、どのように書けるでしょうか。
models.pyを以下のようにします。

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


class Post(models.Model):
"""ブログの記事"""

title = models.CharField('タイトル', max_length=255)
text = models.TextField('本文')
is_publick = models.BooleanField('公開フラグ', default=False)
publick_at = models.DateTimeField('公開日', blank=True, null=True) # これが増えた
created_at = models.DateTimeField('作成日', default=timezone.now)

def __str__(self):
return self.title

def save(self, *args, **kwargs):
# is_publicがTrueで、publick_atがNoneのとき...
# つまり、is_publickをTrueにした初回のみここです
if self.is_publick and not self.publick_at:
self.publick_at = timezone.now()
super().save(*args, **kwargs)




増えたのは、publick_atというDateTimeFieldです。blank=True、null=Trueにしておきます。
そして、saveメソッドを上書きします。is_publickをTrueにした初回だけ、publick_atに現在日付を入れるのです。

後は、views.pyで公開日順に並び替えるだけです。

from django.views import generic
from .models import Post


class IndexView(generic.ListView):
model = Post

def get_queryset(self):
# 公開フラグがTrueで、publick_at順に並び替え
return super().get_queryset().filter(is_publick=True).order_by('-publick_at')