📑
DjangoでCustom Managerを利用して、Railsのfind_by風オブジェクト取得を実現する
書くこと
- Ruby on Railsのfind_by風、簡易機能をDjangoで書く方法
- Djangoのget で ObjectDoesNotExistを握りつぶす方法
利用する技術
- Django
- model.Manager
今日のゴール
このようなArticleモデルが定義されていたとき
class Article(models.Model):
title = models.CharField(max_length=100)
# (省略)
is_active = models.BooleanField(default=True)
呼び出し側では、以下のようにオブジェクトの取得ができる。
# 期待する取得結果:
# Article<(1)> or None
article = Article.get_object_or_none(pk=1)
# 複数ある検索条件の場合:
# MultipleObjectsReturned
article = Article.get_object_or_none(is_active=True)
方法論
CustomManagerを定義
model/manager/base_manager.py
from django.db import models
class BaseManager(models.Manager):
def get_object_or_none(self, **kwargs):
try:
return self.get_queryset().get(**kwargs)
except self.model.DoesNotExist:
return None
ここの処理では意図的に MultipleObjectsReturned
を握りつぶしていません。
Railsのfind_by
では複数件ある場合には1件目を取得するため挙動が異なります。
model/manager/base_manager.py
from .managers.base_manager import BaseManager
class ArticleManager(models.BaseManager)
pass
Articleモデルで利用する
models/article.py
from .managers.article_manager import ArticleManager
class Article(models.Model):
# (前略)
objects = ArticleManager()
参考
- django.shortcutのget_object_or_404
- django DoesNotExistはいらない
Discussion