自動化無しに生活無し

WEBとかAIとかLinux関係をひたすら書く備忘録系ブログ

Djangoでカスタムユーザーモデルを外部キーとして指定する方法【1対多】

thumbnail

例えば、簡易掲示板で投稿者のユーザーIDを外部キーとして指定したい場合がある。

作ったカスタムユーザーモデルを外部キーとして通常のアプリから指定する方法を解説する。

本記事では、下記記事で解説したカスタムユーザーモデルを実装したことを前提として話を進める。

【Django】allauthとカスタムユーザーモデルを実装した簡易掲示板を作る【AbstrastBaseUser】

カスタムユーザーモデルを外部キーとして指定する

まず、settings.pyに下記のような設定がされているとする。usersアプリのCustomUserクラスを指定している。

AUTH_USER_MODEL = 'users.CustomUser'

続いて、任意のアプリのモデルを編集する。

from django.db import models
from django.utils import timezone
from django.conf import settings 
import uuid

class Topic(models.Model):

    id      = models.UUIDField(primary_key=True,default=uuid.uuid4,editable=False)
    dt      = models.DateTimeField(verbose_name="投稿日",default=timezone.now)
    comment = models.CharField(verbose_name="コメント",max_length=2000)
    user    = models.ForeignKey(settings.AUTH_USER_MODEL,verbose_name="ユーザー",on_delete=models.CASCADE)

    def __str__(self):
        return self.comment

このように、まずは冒頭from django.conf import settingsでsettings.pyをインポートする。

続いて、

user    = models.ForeignKey(settings.AUTH_USER_MODEL,verbose_name="ユーザー",on_delete=models.CASCADE)

とする。ForeignKeyの対応するモデルクラスはsettings.AUTH_USER_MODEL、即ち、users.CustomUserのことである。

usersアプリのCustomUserをインポートすればいいじゃんって思うかも知れないが、Pythonの構文上それはできない。できたとしても、settings.pyで指定するカスタムユーザーモデルと外部キーで対応付けるカスタムユーザーモデルに一貫性がなくなってしまう可能性があるため、やめたほうが良いだろう。

ビューのPOST文の処理では以下のようにuserフィールドに値を入れる。

#--省略--

    def post(self, request, *args, **kwargs):

        copied          = request.POST.copy()
        copied["user"]  = request.user.id

        form    = TopicForm(copied)
    
        if form.is_valid():
            form.save()
        else:
            print("バリデーションエラー")

        return redirect("bbs:index")

index   = BbsView.as_view()

.copy()メソッドを使ってコピー、request.user.idにカスタムユーザーモデルのIDが含まれているのでそれを当てる。後はバリデーションをした上でDBに保存すればOK

もし、ユーザーのそれ以外の情報が欲しい場合は、外部キーから参照すれば良い。

結論

これで投稿者のユーザーモデルと紐付けができるので、ハンドルネームを変えたり、プロフィール画像を変えたりしたとしても、投稿内容はIDに紐付いているので追随できる。

今回はユーザーのアカウントが削除されたら同時に投稿内容も削除されるよう、on_delete=CASCADEとした。

ちなみに、カスタムユーザーモデルを使用しない場合(デフォルトのユーザーモデルを使用する場合)、下記を参照。

【Django】ユーザーモデルと1対多のリレーションを組む方法【カスタムユーザーモデル不使用】

スポンサーリンク

シェアボタン

Twitter LINEで送る Facebook はてなブログ