Python

Djangoの司令塔 ビューについて

Djangoの司令塔を担うビューの役割についてまとめておこうと思います。

ビューの目的は主に以下4点ですが、ほぼすべてのファイルに対して指示を出しています。

  • フォーム処理の指示
  • データベース操作の指示
  • テンプレートにhtmlの生成を指示
  • ルーティングに処理を譲渡し、画面移動を円滑に行う

このビューに関してはDjangoの中でも一番理解しずらい内容であると感じていますが、この記事では理解をできるだけしやすいように(忘れても思い出しやすいように)まとめていますので安心してください。

Djangoのビューが難解に感じる理由は、個人的な意見ですが、

記述方法が「関数ベースビュー」と「クラスベースビュー」の2通りの記述方法があるのが難しく感じる理由であると感じています。

この解決法としては、「クラスベースビュー」で記載することだけを考えることです。

初心者は、「関数ベースビュー」の考え方は捨ててもよいと割りきってください。

ビューの構文を覚える

ビューには以下大事なキーワードがあります。

  • クラスベースビュー
  • オーバライドするクラス変数
  • オーバライドするメゾット

この3つは超重要です。

この3つはそれぞれに決まった機能が複数あるのですが、よく使う機能を覚えておく必要があります。

そもそもクラスベースビューやクラス変数やメゾットって何かについて超ざっくり説明します。

クラスベースビューとは

クラスベースビューとは、pythonのクラス機能を利用して何か処理を行うためのひな型です。そして、このビューで使用するクラスは、まとまった処理クラスを利用できるようにDjangoが提供しているクラスを使用して処理を行うことになります。

オーバーライドするクラス変数とは

クラス変数とは、Djangoの1つのプロジェクト内で共通に使用できる変数のことを指しています。つまり、ビューだけで無く、モデルやテンプレートでも同じそのクラス変数が使えることになります。Djangoがあらかじめ決まった文字列に意味を持たせている為、初心者はまずどんな文字列があるのかを知っておく必要があります。ただし、共通で使用する為には、クラスベースビューごとに決まっているので注意が必要です。

メゾットとは

ひな型であるクラスベースビューの中で特定の処理を行う構文です。def~で始まる構文を指しています。クラス変数と同様で、 共通で使用できるメゾットは、クラスベースビューごとに決まっているので注意が必要です。

クラスベースビューの構文

クラスベースビューの構文について軽く触れておきます。クラスビューは大きく3部「参照ヘッダー」「class ベースビュー」「メゾッド」で構成されています。

参照ヘッダー:viewやform,modelから参照するためのヘッダー(何が必要かは覚えるしかないようです)

クラスベースビュー:行いたい処理に合わせてクラスベースビューを設定する。モデルやテンプレートやフォームとの紐付けがここでなされる。

メゾッド:決まった処理を行う。

クラスベースビューについて説明します。下の表は8つの主なクラスベースビューの例を記載しています。使用例については初心者はまだ見なくてもよいです。

クラスベースビュー用途使用例
RedirectViewリダイレクトを処理
(特定のページを開く)
from django.views import generic

class DjangoRedirectView(generic.RedirectView):
url = ‘https://**リダイレクト先のurlを記載**.com/
TemplateViewテンプレート表示
テンプレートにhtmlの生成指示
from django.views import generic

class IndexView(generic.TemplateView):
template_name = “作成するファイル名.html”
ListViewモデルオブジェクトの一覧表示from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Model_A

class DjangoListView(LoginRequiredMixin,generic.ListView):
model = Model_A
template_name = ‘list.html’
def get_queryset(self):
app_A = Model_A.objects.filter(user=self.request.user).order_by(‘-created_at’)
return app_A

CreateViewモデルオブジェクトを作成from .forms import InquiryForm,App_ACreateForm
class appACreateView(LoginRequiredMixin,generic.CreateView):
model = Model_A
template_name = ‘list.html’
form_class = forms.pyで作るクラス
success_url = reverse_lazy(‘appA:appA_list’)←appA_listはurl.pyで作るパス

def form_valid(self,form):
appA = form.save(commit=False)
appA.user = self.request.user
appA.save()
messages.success(self.request,’モデルを作成しました’)
return super().form_valid(form)
def form_invalid(self,form):
messages.error(self.request,”モデルの作成に失敗しました”)
DetailViewモデルオブジェクトの詳細表示 class appADetailView(LoginRequiredMixin,generic.DetailView):
model = Model_A
template_name = ‘appA_detail.html’
UpdateViewモデルオブジェクトの更新class appAUpdateView(LoginRequiredMixin,generic.UpdateView):
model = Model_A
template_name = ‘appA_detail.html’
form_class = appCreateForm
def get_success_url(self):
return reverse_lazy(‘appA:appA_detail’, kwargs={‘pk’:self.kwargs[‘pk’]})

def form_vaild(self,form):
messages.success(self.request,’更新しました’)
return super().form_valid(form)

def form_invaild(self,form):
messages.error(self.request,’更新失敗しました’)
return super().form_invalid(form)
DeleteViewモデルオブジェクトの削除 class appADeleteView(LoginRequiredMixin,generic.DeleteView):
model = Model_A
template_name = ‘ appA_list.html’
success_url = reverse_lazy(‘appA:appA_list’) ←appA_listはurl.pyで作るパス
def delete(self,request, *args, **kwargs):
messages.success(self.request,’モデルを削除しました’)
return super().delete(request, *args,**kwargs)
FormViewフォームに指示from django.views import generic
from .forms import InquiryForm
class IndexView(generic.TemplateView):
template_name = ‘ appA_index.html’
class InquiryView(generic.FormView):
template_name = ‘ appA_inquiry.html’
form_class = InquiryForm

まだ初心者の方は上の表にある8つのクラスベースビューを覚えるのがやっとだと思います。当の私も完全に覚えれていませんが、この記事を書きながら学習しています。

さらにオーバーライドできるクラス変数とメゾッドの例をいくつか紹介しておきます。

クラス変数対応できるクラスベースビュー用途使用例
template_name RedirectView 以外テンプレート名を指定するtemplate_name = ‘index.html’
modelListView,
CreateView,
DetailView
UpdateView,
DeleteView
モデルを指定する
querysetを設定していない場合は必須事項
model = ***Model
paginate_byListView1ページに表示する件数を指定する。paginate_by = 9
querysetListView,
CreateView,
DetailView
UpdateView,
DeleteView
テンプレートにクエリーセットを
modelを使用していない場合は必須。
get_querysetと違い、毎回同じクエリーの時に使える
pueryset = ***
Model_objects.
filter(*** = bar)
from_classCreateView,
UpdateView
FormView
フォームクラス名を指定する。form\class = ***Form
success_urlCreateView,
UpdateView
FormView
処理が成功した場合にリダイレクトさせるURLを指定する。
このURLは動的に変化できない。
success_url = reverse_lazy(‘app:index’)
get_success_urlCreateView,
UpdateView
FormView
処理が成功した場合にリダイレクトさせるURLを指定する。
このURLは動的に変化できる。
get_success_url = reverse_lazy(‘app:index’)
fields CreateView , UpdateView ビューで使うフォームのフィールドを指定する。fields = (‘field1’,field2,)

そして、代表的なメゾッドを紹介しておきます。

メゾッド対応ビュー用途使用例
get_context_data RedirectView 以外 テンプレートに辞書データを渡す際に使用するdef get_context_data(self):
context = super().get_context_data()
context(‘***’) = ***Model.objects.get(user=self.request.user)
return context
get_querysetListView,
CreateView,
DetailView
UpdateView,
DeleteView
テンプレートにクエリーセットを渡す。(querysetと違い、クエリーが都度変更となる場合) def get_queryset(self):
*** = ***Model.objects.filter(user = self.request.user)
return ***
form_validCreateView,
UpdateView
FormView
フォームバリデーションに問題がなければ処理を行う。def get_vali(self, form):
messages.success(self.request,’成功しました’)
return super().form_valid(form)
form_invalidCreateView,
UpdateView
FormView
フォームバリデーションに問題があれば処理を行う。 def get_invali(self, form):
messages.error(self.request,’失敗しました’)
return super().form_invalid(form)
get_success_urlCreateView,
UpdateView
DeleteView,
FormView
処理成功時にリダイレクトするURLを指定する。def get_success_url(self):
return reverse(‘app:detail’,kwargs={‘pk’:self.kwargs[‘pk’]})
deleteDeleteView削除処理に合わせて、ほかの処理を実行する。def delete(self,request,*args,**kwargs):
return super().delete(request,*args,**kwargs)
getRedirectView,
TemplateView, ListView,
CreateView,
DetailView,
UpdateView,
DeleteView,
FormView
get通信時の処理を行うdef get(self,request,*args,**kwargs):
return HttpResponse(‘Hello World’)
postRedirectView,
CreateView,
UpdateView,
DeleteView,
FormView
post通信時の処理を行うdef post(self,request,*args,**kwargs):
form = self.form_class(request.POST)
if not form.is_valid():
return HttpResponseRedirect(reverse_lazy(‘app:index’))
return render(request,self.template_name,{‘form’:form})
ABOUT ME
den
完全独学でWEBデザインを無謀にも挑戦している中年男。 工場勤務の会社員で3児の父。 チャレンジを忘れず、妻に怒られても心はおれず。 有益な情報を発信し、これを見ている人の為になればと思っています。
関連記事一覧