やりたいこと
投稿サイトで新規投稿する際、いちいち自分で自分の名前を打ち込むのではなく、ログイン中のユーザーの情報(自分の名前など)を事前にフォームにセットし、名前を打ち込む手間を省きたい。
1.モデルを用意する
from django.db import models
from django.contrib.auth import get_user_model
class Post(models.Model):
author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
def __str__(self):
return self.title
Postモデルを用意し、3つのフィールド〔投稿者、タイトル、内容〕を設置する。
author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
のget_user_model()
で現在ログインしているユーザーのクラスを丸ごと呼び出しており、この1行でauthor
フィールドとログインユーザーが紐づけられる。
ユーザーモデルへの参照方法はいくつかあるが直接Userモデルを参照するのはよくないとされている。
参考:https://djangobrothers.com/blogs/referencing_the_user_model/
2.フォームを用意する。
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta():
model = Post
fields = (
'title',
'content',
)
今回はモデルフォームを用いた。Djangoが用意してくれているforms.pyに含まれるModelFormを継承しPostFormクラスを作成する。
model = Post
で引き継ぐモデルを指定し、authorを除く二つのフィールドを指定する。ここでauthorをわざわざ指定する必要がなくなる。
3.ビューでログインユーザーをセットする
from django.shortcuts import render, redirect
from .models import Post
from . import forms
def form_view(request):
if request.method == 'POST':
form = forms.PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('sns:index')
else:
form = forms.PostForm()
return render(request, 'sns/form_view.html', {'form': form})
form_view関数ではrequestとしてPOSTを受け取るか(if request.method == 'POST':
)GETを受け取るか(else:
)で挙動を変える必要がある。例えば、新規投稿というボタンが押されて、URLディスパッチャによりform_view関数が呼び出されるとrequestは'GET'となるので、下に示す通り単純にフォームを表示するだけの処理が実行される。
else:
form = forms.PostForm()
return render(request, 'app/form_view.html', {'form': form})
その表示したフォームに何かしら入力され、送信ボタンが押されURLディスパッチャによりform_view関数が呼び出されると、今度はrequestが'POST'となるので下に示すコードが実行される。
if request.method == 'POST':
form = forms.PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.save()
return redirect('app:index')
1. form = forms.PostForm(request.POST)
によって入力された情報をformに格納する。
2. if form.is_valid():
で入力された情報に誤りがないか確認し、post = form.save(commit=False)
でform
をセーブする。このとき引数にcommit=False
とし完全にセーブする前にもう少し手を加えるということを伝える。
3. post.author = request.user
でpostのauthorフィールドにrequest
したuser
(つまりログイン中のユーザー)を指定する。
4. post.save()
でフォームに入力された内容、及びログイン中のユーザー名をセーブする。
5. return redirect('app:index')
でリダイレクト先を指定する。