※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part6)〜QuerySet(練習編)~
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part8)〜View関数の作成~

【初心者チュートリアル】Django2でブログ作成(Part7)〜ModelManager~

web開発 python3 Django python Djangoチュートリアル

投稿日:2019年11月11日

このエントリーをはてなブックマークに追加
Djangoは簡単にWebアプリケーションを作成できるフレームワークです。この記事は初心者の方向けのDjangoチュートリアルです。

はじめに

今回のチュートリアルの内容のModelMangerは開発していく中で必須のものではありません。
しかし、これを使いこなすことでコードは非常に完結に見やすくなります。


Manger

Managerとは?

Djangoにおけるマネージャ (Manager) とは、Django のモデルに対するデータベースクエリの操作を提供するインターフェイスです。Django アプリケーション内の1つのモデルに対して、Manager は最低でも1つは存在します。

ModelのデフォルトのManger

前回いろんなQueryを実行してみる中でobjectsという変数を呼び出していました。

全件取得をするQuerySetの呼び出し
articles = Article.objects.all()

この様にModelクラスdjango.db.models.Modelを継承した段階で、objectsというクエリを呼び出すManagerがついています。

継承しているので今見えていないですが、本当はArticleには下の様にobjectsという変数があります。

sample_blog/blog/models.py
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User


class Article(models.Model):
    objects = models.Manager()             # 見えていないが実際にはこれがある
    [...]

QuerySetの呼び出しなどで見たobjectsはこれだったんですね!

ここで少し実際にブログのコードを作成する場面をイメージしてみましょう。ブログのトップページや、関連記事、人気記事ランキングや記事の詳細ページ、おそらくユーザーに見せる殆どのページは公開中(statusがpublished)の物になるでしょう。

このままだとコードを作成していく中で、大量にArticle.objects.filter(status="published")と書く事になります。これはコードの可読性的にも、コードを管理していく面から見ても得策ではないでしょう。

ここで新しいカスタムManagerを作成することでこの問題を解決してみましょう。

PublishedManagerの作成

models.pyに新しくPublishedManagerを作成し、Articleモデルで設定してみます。

sample_blog/blog/models.py
[...]
class PublishedManager(models.Manager):
    """
    デフォルトで公開中のもののみを取得
    """
    def get_queryset(self):
        return super(PublishedManager, self).get_queryset().filter(status="published")

class Article(models.Model):
    [...]
    objects = models.Manager() 
    published = PublishedManager()    # managerを追加
    
    [...]

このPublishedManagerは公開中の物のみを取得するManagerです。これによってArticleモデルは次の様に公開中の記事を取得できます。

$ python manage.py shell
>>> from blog.models import Article
>>> Article.published.filter(author__username="marsquai")
<QuerySet [<Article: エンジニアの健康維持の秘訣とは?>, <Article: 君にもできるスクレイピング!>, <Article: Shellから変更された記事>, <Article: シェル記事>, <Article: 今夜の料理は?>]>

上の様にArticle.publishedPublishManagerを呼び出した時、このManagerget_queryset()メソッドが呼ばれます。このメソッドはQuerySetを返すメソッドです。

今回、このメソッドをオーバーライドして公開中のもののみのフィルタリングをしたことでデフォルトのフィルタがついたというわけですね!


さいごに

なんとなく書いていたobjectsの意味が理解できたでしょうか?

コード中のfilter()で同じ条件のfilter()が増えた時には、カスタムのMangerを使うことを考えてみましょう。

わからなくなったら公式ドキュメントを参照しましょう。

公式ドキュメント:https://docs.djangoproject.com/ja/2.2/topics/db/managers/

このエントリーをはてなブックマークに追加

<前のページ
【初心者チュートリアル】Django2でブログ作成(Part6)〜QuerySet(練習編)~
次のページ>
【初心者チュートリアル】Django2でブログ作成(Part8)〜View関数の作成~

関連記事

記事へのコメント