Self-Curation

新卒社会人で営業マンになりました

#Django2 リダイレクトページを挟んで投稿時に任意の処理を行う

f:id:scuration:20200607213312p:plain

前回の記事ではDjangoの汎用ビューを使って投稿フォームを簡単に作成できました。

シンプルな機能であれば汎用ビューは他言語・フレームワークにはない便利なものです。

しかしその分融通が利かないデメリットがあるとも感じています。

例えば「投稿と同時にデータベースに任意の処理を加えたい」という場合です。

今回は任意の処理を行うためのリダイレクトページを挟むことによる解決策を書いていきたいと思います。

関数とは

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world!")



上記のようなdefから始まるものは関数と呼ばれるものです。
こちらのサンプルコードの場合、urls.pyで設定した上でexample.com/indexにアクセスすると「Hello World」を返すものとなっております。

投稿と同時処理はできなさそう


defから始まる処理は基本的にページが読み込まれた段階で処理されます。

なので「投稿フォームのメールアドレスを継承→メールアドレスから固有のパラメータを作成→送信したデータと一緒にデータベースに保存」といったことは難しそうです。

ただしリダイレクトページにパラメータを継承することは簡単なので、今回はその方法を試したいと思います。

リダイレクトページの生成

フォーム送信後にリダイレクトページに飛ぶにはViewを以下のように記述します。

from django.urls import reverse_lazy
from django.views.generic import CreateView
from .models import PostModel

class NewReviewClass(CreateView):
    template_name = 'newreview.html'
    model = PostModel
    fields = ('title','url','comment',)    

    def get_success_url(self):
         return reverse('redirect', kwargs={'pk': self.object.id})

ポイントはget_success_urlの関数です。
''で囲まれているredirectは後程urls.pyで設定する名前で、保存された各データに割り振られるid(プライマリーキー)を'pk'として継承。

urls.pyでは以下のようにリダイレクトページのパスを指定します。

path('redirect/<int:pk>', redirect, name='redirect'),

name=はget_success_urlの値と合うようにredirectにします。
これでexample.com/redirect/PK(プライマリキー)のページが自動的に生成され、遷移します。

リダイレクトページにデータ継承

from django.urls import path
from django.conf.urls import url
from .views import NewReviewClass
from .views import redirect

urlpatterns = [
    path('newreview/', NewReviewClass.as_view(), name='newreview'), 
    path('redirect/<int:pk>', redirect, name='redirect'),
]

urls.pyについては上記のような感じになると思います
path()の中にある2番目のredirectは実際に生成されたリダイレクトページに対応するviewを指定します。

from django.urls import reverse_lazy
from django.views.generic import CreateView
from .models import PostModel

class NewReviewClass(CreateView):
    template_name = 'newreview.html'
    model = PostModel
    fields = ('title','url','comment',)    

    def get_success_url(self):
         return reverse('redirect', kwargs={'pk': self.object.id})

def redirect(request, pk):
    return render(request, 'redirect.html', {'id': id})

これで「フォーム送信→フォームのデータを継承したリダイレクトページに飛ぶ」という流れは出来ているはずです。