(最終更新月:2021年12月)
「OneToOneFieldって何?ForeignKeyフィールドと何が違うの?」
「特定のモデルクラスを拡張して使えるようにしたい!」
などというDjango初学者の方へ向けての記事となります
当記事を通じて、
- OneToOneFieldとは何か?特長とは?
- OneToOneFieldの実例
について解説・紹介していきます
まずは、「OneToOneFieldとは何か?」から始めていきましょう!
✔YouTube解説動画
当記事の内容は動画を見ながら進めると、約15分程度で完了します。
動画ならではの情報も解説しているので、記事と一緒にご覧ください。
動画の概要欄には、単元ごとのコードを紹介しているgithubページも載せています。
OneToOneFieldとは?
モデルクラス同士を一対一の関係で紐付けるためのフィールド
になります
対して、ForeignKeyフィールドは多対一と表すことができます
違いを見ていくことでもう少し理解を深めていきましょう
【ForeignKeyの例】
class NippoModel(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
#...
ForeignKeyフィールドで指定されているユーザーは複数の日報を持つことが可能です
日報、日記、ツイート、などの作者・著者などとして使用できます
【OneToOneFieldの例】
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
#...
OneToOneFieldで指定されているユーザーは複数のProfileを持つことは許されません
ユーザークラスで用意されているフィールドを拡張し、プロフィールを充実させたい場合などに使用できます
具体的にOneToOneFieldの特長を見ていきます
OneToOneFieldの特長
紐付けられているオブジェクトへ、属性(プロパティ)としてアクセスができる
ことがForeignKeyと比較した際、特に違いとして際立つポイントになります
前章の例ですと、以下のどちらも成り立ちます。
- ユーザーオブジェクト.profile
- プロフィールオブジェクト.user
また、プロフィールが作られているかを確認するためには、hasattrメソッドが使えます。
なぜならプロフィールを持っていないユーザーに、「profile」属性は存在しないからです。
hasattr(ユーザーオブジェクト, ‘profile’)
プロフィールが存在する場合は「True」、プロフィールが存在しない場合は「False」を返します。
前章でカンタンにご紹介してますが、サンプルとして日報アプリで使うプロフィールモデルクラスを定義しましたので参考になれば幸いです
【実例コード】Profileクラス
【accounts > models.py】
#models.pyの上部に記述
GENDER_CHOICE = [(None, "--"), ("m", "男性"), ("f", "女性")]
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
username = models.CharField(max_length=100, verbose_name="ユーザー名")
department = models.CharField(max_length=100, blank=True, null=True, verbose_name="部署")
phone_number = models.IntegerField(blank=True, null=True, verbose_name="携帯番号")
gender = models.CharField(max_length=1, choices=GENDER_CHOICE, default=None, verbose_name="性別", blank=True, null=True)
birthday = models.DateField(blank=True, null=True, verbose_name="生年月日")
def __str__(self):
return self.username
OneToOneFieldに加えて、必要と思われる項目も追加し、特に必須でない項目には「blank=True, null=True」を追加しています
【accounts > admin.py】
admin.site.register(Profile)
アドミンページでアクセスできるよう「register」します
まとめ
OneToOneFieldには、
- 単一のオブジェクトとのみ紐づけることができる
- 属性として双方からアクセスが可能になる
などの特長があります
元のモデルクラスでフィールドを増やしていくのではなく、OneToOneFieldを使い、必要に応じてモデルクラスを拡張していくことをオススメします
さて、こうなるとあると便利なのが、Admin画面で一つのページで「User」「Profile」がどちらも保存できる機能です
現状ではそれぞれ別のページで保存することになっています
次回はAdminページのフォームをカスタマイズしていく方法をお伝えします