DjangoBrothers BLOG ✍️

2018/07/29

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

Django Userモデルへの参照方法(AUTH_USER_MODEL, get_user_modelの使い方)

今回のエントリーでは、Djangoの根幹的な機能であるUserモデルへの参照について整理してみます。

Djangoには標準で備わっている強力なUserモデルが存在し、viewなどからはdjango.contrib.auth.modelsUserを参照することで利用することができます。

しかし、※Djangoの公式ドキュメントでも言及されている通り、自分のプロジェクトのなかでこのデフォルトのUserモデルをそのまま利用するのは避けるべきです。その場合、独自に定義したCustom Userを作成することになりますが、その場合の最適なUserモデルへの参照はどのように行うべきでしょうか?また、外部のreusableなDjangoアプリを利用したり、他の人が利用するDjango アプリを自分で作成したりする場合に、いろんな箇所で別々のUserモデルを参照するということも起きるかもしれません。

※ Django公式ドキュメントでは、『新しくプロジェクトを始める場合は、デフォルトの User で十分である場合でも、カスタムユーザーモデルを作成することを強く推奨します。』と記載されています。これは、プロジェクトで後々Userモデルの設計を変更したくなったときに柔軟に対応できるようにするためです。

そこで、そういった事情も考慮した、最適なUserモデルへの参照方法が設定されています。Userモデルへの参照方法は大きく以下の3つが存在しますが、それぞれの機能を整理した上で、一番オススメの方法をご紹介します。

  1. 直接Userを参照する
  2. AUTH_USER_MODELを参照する
  3. get_user_model( )で呼び出す

直接Userを参照する

まずは、django.contrib.auth.modelsUserを直接呼び出すパターンです。

models.py

from django.db import models
from django.contrib.auth.models import User

class Article(models.Model):
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
    )
    title = models.CharField(max_length=100)
    text = models.TextField()

DjangoのデフォルトのUserモデルを利用する場合にはこのような書き方をすることができます。しかし、先ほども言及したように、デフォルトのUserモデルを利用することは非推奨となっているため、現実的にはこのような書き方はしないようにしましょう。そこで、他のパターンをみていきます。

AUTH_USER_MODELを参照する

代替案の一つ目は、AUTH_USER_MODEL(ドキュメント)を参照することです。

AUTH_USER_MODELは下記のようにsettings.pyに設定して利用します。ここでは新たにusersというアプリを作成し、その中に通常のUserモデルを継承したCustomUserを作成したことを想定しています。

ここでひとつ注意点ですが、一度デフォルトのユーザーモデル(auth.User)を使用してマイグレーションをしてしまうと、あとからCustom Userを使用するのは非常に大変な作業が必要になります。Custom Userを使用する場合には、Custom Userモデルを作成する前のマイグレーションは絶対にしないようにしましょう。

settings.py

AUTH_USER_MODEL = 'users.CustomUser'

このようにAUTH_USER_MODELを設定すると、models.pyでは以下のように参照することができます。

models.py

from django.conf import settings
from django.db import models

class Article(models.Model):
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    title = models.CharField(max_length=100)
    text = models.TextField()

settings.pyに指定したAUTH_USER_MODELを参照することで、より柔軟な設定にすることができました。

get_user_model( )で呼び出す

もう一つの方法は、django.contrib.authget_user_model( )を利用する方法です。get_user_model( )では、現時点で有効になっているUserモデル自体を呼び出してくれます。つまり、AUTH_USER_MODELにCustomUserが指定されている場合はCustomUserを、デフォルトのUserのままであればUserモデルを呼び出します。モデルクラスへの設定の仕方は以下のようになります。

models.py

from django.contrib.auth import get_user_model
from django.db import models

class Article(models.Model):
    author = models.ForeignKey(
        get_user_model(),
        on_delete=models.CASCADE,
    )
    title = models.CharField(max_length=100)
    text = models.TextField()

実はget_user_model( )にはモデルフィールドへの設定時にうまく読み込みがされないという問題があったのですが、Django1.11以降ではこの問題は解決されています。

また、AUTH_USER_MODEL自体はStringクラスであるのに対して、get_user_model( )はUserクラス自体を返します。

AUTH_USER_MODELとget_user_model()

# AUTH_USER_MODEL
>>> from django.conf import settings
>>> settings.AUTH_USER_MODEL
'auth.User'
>>> type(settings.AUTH_USER_MODEL)
<class 'str'>

# get_user_model()
>>> from django.contrib.auth import get_user_model
>>> user = get_user_model()
>>> user
<class 'django.contrib.auth.models.User'>

そのため、たとえばviewなどから直接Userモデルを呼び出す場合には、UserModel = get_user_model( )のように書くことはできますが、UserModel = settings.AUTH_USER_MODELのように指定することはできません。

まとめ

今回のエントリーでは、DjangoでのUserモデルの参照方法のパターンを紹介しました。Django1.11より前のバージョンでは、get_user_model( )をモデルフィールドで利用できなかったので使い分ける必要がありましたが、こちらはすでに修正済みとなっているので、基本的にいつでも、get_user_model( )を利用するのがいいと思います。

カスタムユーザーモデルについては、書籍でも解説しています。