ITの窓辺から

三流IT技術者の日常

DjangoでLDAP認証 その2 AbstractUserとAbstractBaseUser

前回の記事ではDjangoLDAP認証を行うための相当前段階に関する話をしていたのでした。

realizeznsg.hatenablog.com

今回はその続きとして認証バックエンドについてやっていこうと思っていたのですが、ユーザーモデルについてもう少し調べていたら、もう少し理解しておいたほうが良さそうなことが出てきたので一旦ブレーキをかけて、ユーザーモデルの話です。

前回の記事にも書きましたが、これは解説記事ではなく初心者によるメモです。今回のようにすぐに追記すべき事項が出てくることが頻発すると予想されるため、鵜呑みにすると危険です。

動作環境は以下の通りです。
macOS(intel CPU) Big Sur
Python3.8.5 (venv環境)
Django3.2.5

AbstractBaseUser

前回の記事でユーザーモデルの本質はAbstractUserである、というようなことを書きましたがこれは正確ではなさそうです。AbstractUserのコードを見ると、AbstractBaseUserを継承しています。名前からして抽象クラスのようですが、Pythonの記法で抽象クラスとして書かれているようには見えませんでした。このクラスはDjangoの認証アプリケーションのmodels.pyにはなく、同アプリケーション内のbase_user.pyに記述がありました(models.pyでimportしている)。

AbstractBaseUserの中身を見てみると・・・、AbstractUserと違ってユーザーモデルの初期フィールドとなる設定がほぼありませんでした。しかしAbstractUserには定義されていないメソッドが多数あります。メソッド名を見る限り、ユーザーモデルの操作やバリデーションを行うために必要そうな機能がありそうです。

AbstractUserはAbstractBaseUserを継承しており、AbstractBaseUserのメソッドが使用できます。そのため、AbstractUserはユーザーモデルの実装の一例であり、ユーザモデルの本質はAbstractUserではなくAbstractBaseUserである、という方が正しそうです。

ユーザーモデルのカスタマイズ

自分の中でも整理できていなかったのですが多少ましになったので再度ここで整理します。

デフォルトのユーザーモデルを使用すると後でユーザーモデルを変更することが難しいので推奨しない、という公式ドキュメントのお触れがあります。そのため、前記事の通り新しくDjangoアプリケーションを作りその中でユーザーモデルを定義し、それをユーザーモデルとして使用することはユーザーモデルのカスタマイズというより儀式として行うことになります。表現を変えるならユーザーモデルのカスタマイズというより別のユーザーモデルを使用するようにする、というようになるでしょうか。この文脈でのユーザーモデルのカスタマイズの主目的は後のユーザーモデルの変更難易度を上げないことなので、新しいユーザーモデルではAbstractUserを継承し、内容はpassとしておくのが良さそうです。

続いて、本当にデフォルトのユーザーモデルでは要件を実現できないときに初めてユーザーモデルのカスタマイズを行います。このカスタマイズの実現方法はAbstractBaseUserを継承したユーザーモデルを作成する、というのが基本的な考え方と思われます。

AbstractUserはAbstractBaseUserの実装なので、これを再利用する形としても良いと思いますが、場合によっては不要なフィールドがあったりもするのでデータベースに反映する際に余計な領域を作ることにもなります(もちろんコードから消せば良いのですが)。そのため、ユーザーモデルをカスタマイズするのであれば、AbstractBaseUserを継承したクラスを作成し、場合によっては「楽をするために」AbstractUserからコードをコピーして新しいユーザーモデルを作れば良いように思えます。

公式ドキュメントを読むと、ユーザーモデルのカスタマイズを行うにはとりあえずAbstractBaseUserを継承しろと書いてあるんですよね・・・。基本的な部分がある程度分かっている、または予測が付く状態の人が公式ドキュメントを読むとすごい速度で吸収できるんでしょうけど、何が分からないのかよくわからないような状態で読むと吸収スピードがおそすぎですね。