Django ORMのfirst・last入門
最初・最後のデータを取得する方法
Django ORMのfirst()とlast()メソッドを使って、QuerySetの最初または最後のデータを安全に取得する方法を解説します。
こんな人向けの記事です
- Django ORMで先頭や末尾のデータを取得したい人
- first()とget()の違いを理解したい人
- latest()やearliest()の使い方を知りたい人
Step 1first()の基本
first()はQuerySetの最初の1件を返します。データが存在しない場合は例外ではなくNoneを返すため、安全に使えます。
Python
# models.py
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
view_count = models.IntegerField(default=0)
is_published = models.BooleanField(default=False)
class Meta:
ordering = ["-created_at"]
def __str__(self):
return self.titlePython
# 最初の1件を取得
article = Article.objects.first()
if article:
print(f"最初の記事: {article.title}")
else:
print("記事がありません")
# order_by()と組み合わせる
oldest = Article.objects.order_by("created_at").first()
print(f"最も古い記事: {oldest.title}")
most_viewed = Article.objects.order_by("-view_count").first()
print(f"最も閲覧された記事: {most_viewed.title}")
# filter()と組み合わせる
latest_published = Article.objects.filter(
is_published=True
).order_by("-created_at").first()
if latest_published:
print(f"最新の公開記事: {latest_published.title}")実行結果
最初の記事: Django ORM活用術
最も古い記事: はじめてのPython
最も閲覧された記事: Django入門ガイド
最新の公開記事: Django ORM活用術Step 2last()の基本
last()はQuerySetの最後の1件を返します。first()と同様に、データがない場合はNoneを返します。
Python
# 最後の1件を取得
article = Article.objects.last()
if article:
print(f"最後の記事: {article.title}")
# order_by()と組み合わせ
# created_at昇順の最後 = 最新の記事
newest = Article.objects.order_by("created_at").last()
print(f"最新の記事: {newest.title}")
# 最も閲覧が少ない記事
least_viewed = Article.objects.order_by("-view_count").last()
print(f"最も閲覧が少ない: {least_viewed.title}")実行結果
最後の記事: はじめてのPython
最新の記事: Django ORM活用術
最も閲覧が少ない: テスト記事orderingの影響に注意
Metaクラスでorderingが設定されている場合、first()とlast()はその並び順に従います。ordering = ["-created_at"]の場合、first()は最新の記事を返します。明示的にorder_by()を指定すると上書きされます。Step 3latest()とearliest()
latest()とearliest()は日時フィールドを基準に最新・最古のデータを取得する専用メソッドです。
Python
# latest(): 指定フィールドの値が最大(最新)のレコード
latest_article = Article.objects.latest("created_at")
print(f"最新: {latest_article.title} ({latest_article.created_at})")
# earliest(): 指定フィールドの値が最小(最古)のレコード
earliest_article = Article.objects.earliest("created_at")
print(f"最古: {earliest_article.title} ({earliest_article.created_at})")
# filter()と組み合わせ
latest_published = Article.objects.filter(
is_published=True
).latest("created_at")
print(f"最新の公開記事: {latest_published.title}")
# Metaクラスでget_latest_byを設定すると引数を省略できる
class Article(models.Model):
title = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
get_latest_by = "created_at"
# 引数なしで呼べる
latest = Article.objects.latest() # created_atが最新のもの実行結果
最新: Django ORM活用術 (2025-01-15 10:30:00)
最古: はじめてのPython (2024-03-01 09:00:00)
最新の公開記事: Django ORM活用術latest()とearliest()の例外
latest()とearliest()は該当データがない場合、DoesNotExist例外を発生させます。first()のようにNoneを返しません。データがない可能性がある場合はtry-exceptで囲むか、first()を使ってください。Step 4first()とget()の使い分け
Python
# get(): 1件だけ取得(0件や2件以上で例外)
try:
article = Article.objects.get(title="Django入門")
except Article.DoesNotExist:
print("見つかりません")
except Article.MultipleObjectsReturned:
print("2件以上見つかりました")
# first(): 最初の1件またはNone(例外なし)
article = Article.objects.filter(title="Django入門").first()
if article:
print(article.title)
# 比較表
# | メソッド | 0件時 | 1件時 | 2件以上時 |
# |-------------|--------------|------------------|----------------------|
# | get() | DoesNotExist | インスタンス | MultipleObjects |
# | first() | None | インスタンス | 最初の1件 |
# | last() | None | インスタンス | 最後の1件 |
# | latest() | DoesNotExist | インスタンス | 最新の1件 |
# | earliest() | DoesNotExist | インスタンス | 最古の1件 |
# | [0] | IndexError | インスタンス | 最初の1件 |Step 5実践的な使用例
Python
# views.py
from django.shortcuts import render
from .models import Article
def home(request):
# 最新の公開記事5件
latest_articles = Article.objects.filter(
is_published=True
).order_by("-created_at")[:5]
# 最も人気の記事
most_popular = Article.objects.filter(
is_published=True
).order_by("-view_count").first()
# 最新の記事(latest()を使用)
try:
newest = Article.objects.filter(
is_published=True
).latest("created_at")
except Article.DoesNotExist:
newest = None
context = {
"latest_articles": latest_articles,
"most_popular": most_popular,
"newest": newest,
}
return render(request, "home.html", context)
# ユーザーの最終ログイン日を取得
def user_profile(request, user_id):
from django.contrib.auth.models import User
user = User.objects.get(id=user_id)
print(f"最終ログイン: {user.last_login}")
# ユーザーの最新の記事
latest = Article.objects.filter(
author=user
).order_by("-created_at").first()
if latest:
print(f"最新記事: {latest.title}")まとめ
first()はQuerySetの最初の1件を返し、0件ならNoneを返すlast()はQuerySetの最後の1件を返し、0件ならNoneを返すlatest()とearliest()は日時フィールド基準で取得(0件時は例外)- データの有無が不確実な場合は
first()が最も安全 - ユニークなフィールドでの検索には
get()、それ以外はfirst()を使い分ける