[Django] get_or_noneメソッド

Twitterでご指摘いただいた、get_query_setをget_querysetに修正しました。Django 1.6 release notes

Djangoで、「モデルクラス.objects.get(条件)」といった形でクエリを発行した場合、ヒットしなかった場合は「モデルクラス.DoesNotExist」という例外が発生します。これを「try-except」で毎回ハンドリングするのは結構面倒です。なので、「get_or_none」という、ヒットしたらモデルを、ヒットしなかったら「None」を返すメソッドを用意しておくと便利です。

「get_or_none」はカスタムマネージャーを使って、以下のように定義するのがきれいなのかなと思います。

from django.db import models


class BaseManager(models.Manager):
    def get_or_none(self, **kwargs):
        """
        検索にヒットすればそのモデルを、しなければNoneを返します。
        """
        try:
            return self.get_queryset().get(**kwargs)
        except self.model.DoesNotExist:
            return None


class Foo(models.Model):
    objects = BaseManager()
    name = models.CharField(max_length=200)
    slug = models.SlugField()
    ...

こんな感じで定義しておくと、後は

# DBにid=1のレコードがあればそのモデル、なければNoneを返します。
foo = Foo.objects.get_or_none(id=1)

といった形で「get_or_none」メソッドを使えるようになります。

もし、「Foo」クラスに独自のマネージャーを持たせたくなった場合は、

class BaseManager(models.Manager):
    ...


class FooManager(BaseManager):
    def get_deleted_foos(self):
        ...


class Foo(models.Model):
    objects = FooManager()
    ...

とすれば、「get_or_none」メソッドを維持したまま、他メソッドを自由に追加していくことができます。

この記事が役に立った場合、シェアしていただけると励みになります!!