Multiple User Types With Custom Data Fields | Djangoという動画中に出てくるコードを見て、自分にとっては謎の挙動だったので調べました。
具体的には以下のようなコードが動画中で書かれていました。
class DriverMore(User): user = models.OneToOneField(User, on_delete=models.CASCADE) model = models.CharField(max_length=255) make = models.CharField(max_length=255) year = models.IntegerField() class Driver(User): base_type = User.Types.DRIVER objects = DriverManager() @property def more(self): return self.drivermore
疑問点としては、この中のDriver
のmore
が「なぜDriver
とは別のDriverMore
クラス」に対してアクセス出来るようになっているのか分かりませんでした。
理由について
Djangoの公式リファレンスによると、以下の記述がありました。
Assuming an existing Employee Fred Smith who has both a User and Employee model, you can access the related information using Django's standard related model conventions:
Djangoの挙動によって関連づけられ、アクセスできるということが分かりました(実際にはUserとEmployee model の例が一緒に書かれているので後半部分の記述が主な理由です)。
https://docs.djangoproject.com/ja/5.0/topics/auth/customizing/#extending-the-existing-user-model
手元でも書いてみたサンプルコード
例えば、以下のようなコードがあるとします。
from django.db import models from django.contrib.auth.models import User class More(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) address = models.TextField() postal_code = models.CharField(max_length=7)
そして、以下のようなコードをmanage.py shell コマンドで実行してみます。
from django.contrib.auth.models import User nibu = User.objects.create_user(username="nibu", email="nibu@example.com", password="nibu") from drivers.models import More nibu_more = More(user=nibu, address="住所", postal_code="0123456") nibu.more.address # 住所 nibu.more.postal_code # 0123456
この挙動から、変数nibu
、すなわちUser
クラスにはmore
という属性は本来はありませんが、OneToOneField
を利用したことでmore
にアクセス出来る事が自身の手を動かしてみても確認できました。
また、反対にmoreから辿ることも出来ました。
nibu_more.user # <User: nibu> nibu_more.user.username # nibu nibu_more.user.email # nibu@example.com
最初、Pythonは同じファイルに書いたクラスにアクセス出来るんだっけ・・・?と驚いたが、Djangoの特性?によるものだったのでまだまだ知らない挙動がありそうだなと実感しています。
補足
ちなみに、こういうModelはProfile modelと呼ばれているそうです。
https://docs.djangoproject.com/en/5.0/topics/auth/customizing/#extending-the-existing-user-model
より以下の記述がありました。
This one-to-one model is often called a profile model
認証情報以外のユーザーに関連するデータを保持する、というのは良くあるケースと聞いて、確かにそうだな、と感じました。
そして、自社の自走プログラマーにも以下のようなページがあることを教えてもらって、自走プログラマーの内容を理解していたらもっと早く理解できていたのだろう、と思いました・・・。