Python | Django | class-based viewsのRedirectViewの使い方
公開日:2021/8/22
Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.
class-based viewsは,viewsを実装する手段の1つであり,関数の代わりにPythonのオブジェクトとしてviewsを定義する.viewsの作成とデータの追加・更新・削除が容易になる.
前記事では,「class-based viewsのFormViewの使い方」を作成した.前記事での設定をそのまま引き継いだ上で,本記事では,「class-based viewsのRedirectViewの使い方」を以下5つの構成にて記す.
◆実施環境
Python 3.8.8
Django 3.2.3
VS Code 1.59.0
■class-based viewsのRedirectViewの使い方
与えられたURLにリダイレクトさせる際にRedirectViewが利用される.
“ec_site/urls.py"に追記し,以下のように編集する.
from django.urls import path
from .views import (
TopView, HomeView, MedicineDetailView,
MedicineListView, MedicineCreateView,
MedicineUpdateView, MedicineDeleteView,
MedicineFormView,
)
from django.views.generic.base import RedirectView # 追記箇所
app_name = 'ec_site'
urlpatterns = [
path('top/', TopView.as_view(), name='top'),
path('home/', HomeView.as_view(), name='home'),
path('detail_medicine/', MedicineDetailView.as_view(), name='detail_medicine'),
path('list_medicines', MedicineListView.as_view(), name='list_medicines'),
path('list_medicines/', MedicineListView.as_view(), name='list_medicines'),
path('insert_medicine/', MedicineCreateView.as_view(), name='insert_medicine'),
path('update_medicine/', MedicineUpdateView.as_view(), name='update_medicine'),
path('delete_medicine/', MedicineDeleteView.as_view(), name='delete_medicine'),
path('form_medicine/', MedicineFormView.as_view(), name='form_medicine'),
path('shelokuma/', RedirectView.as_view(url='https://shelokuma.com' )), # 追記箇所
]
VS Codeの"View"を開き,"Terminal"をクリックする.クリックするとVS Codeの下部にターミナルが開くので,”conda activate 仮想環境名”を実行し,仮想環境に移行する(移行方法の詳細はこちら).その後,ターミナルで"cd class_based_view"を入力し,ディレクトリを変更する.変更後,以下のように”python manage.py runserver”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewtest\class_based_view
>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced). # 以下出力箇所
August 22, 2021 - 17:40:02
Django version 3.2.3, using settings 'class_based_view.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
上記の"http://127.0.0.1:8000/"をクリックすると,ブラウザが開き,以下画面が出力される.
ブラウザのURLに"http://127.0.0.1:8000/ec_site/shelokuma"と入力すると,以下ページ(https://shelokuma.com)に遷移する.
“ec_site/views.py"に追記し,以下のように編集する.
from django.shortcuts import render
from django.views.generic.base import ( # 変更箇所
View, TemplateView, RedirectView,
)
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import (
CreateView, UpdateView, DeleteView,
FormView,
)
from . import forms
import random
from .models import Medicines
from datetime import datetime
from django.urls import reverse_lazy
class TopView(View):
def get(self, request, *args, **kwargs):
medicine_form = forms.MedicineForm()
return render(request, 'top.html', context={
'medicine_form': medicine_form,
})
def post(self, request, *args, **kwargs):
medicine_form = forms.MedicineForm(request.POST or None)
if medicine_form.is_valid():
medicine_form.save()
return render(request, 'top.html', context={
'medicine_form': medicine_form,
})
class HomeView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['name'] = kwargs.get('name')
context['alphabet'] = random.randint(0,9999)
return context
class MedicineDetailView(DetailView):
model = Medicines
template_name = 'medicine.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['time'] = datetime.now()
return context
class MedicineListView(ListView):
model = Medicines
template_name = 'medicine_list.html'
def get_queryset(self):
qs = super(MedicineListView, self).get_queryset()
if 'name' in self.kwargs:
qs = qs.filter(name__startswith=self.kwargs['name'])
qs = qs.order_by('-id')
return qs
class MedicineCreateView(CreateView):
model = Medicines
fields = ['name', 'description', 'price']
template_name = 'insert_medicine.html'
def form_valid(self, form):
form.instance.create_time = datetime.now()
form.instance.update_time = datetime.now()
return super(MedicineCreateView, self).form_valid(form)
def get_initial(self, **kwargs):
initial = super(MedicineCreateView, self).get_initial(**kwargs)
initial['price'] = '1000'
return initial
class MedicineUpdateView(UpdateView):
template_name = 'update_medicine.html'
model = Medicines
form_class = forms.MedicineUpdateForm
class MedicineDeleteView(DeleteView):
model = Medicines
template_name = 'delete_medicine.html'
success_url = reverse_lazy('ec_site:list_medicines')
class MedicineFormView(FormView):
template_name = 'form_medicine.html'
form_class = forms.MedicineForm
success_url = reverse_lazy('ec_site:list_medicines')
def get_initial(self):
initial = super(MedicineFormView, self).get_initial()
initial['price'] = '2000'
return initial
def form_valid(self, form):
if form.is_valid():
form.save()
return super(MedicineFormView, self).form_valid(form)
class MedicineRedirectView(RedirectView): # 以下追記箇所
url = 'https://shelokuma.com'
“ec_site/urls.py"に追記し,以下のように編集する.
from django.urls import path
from .views import ( # 変更箇所
TopView, HomeView, MedicineDetailView,
MedicineListView, MedicineCreateView,
MedicineUpdateView, MedicineDeleteView,
MedicineFormView, MedicineRedirectView,
)
from django.views.generic.base import RedirectView
app_name = 'ec_site'
urlpatterns = [
path('top/', TopView.as_view(), name='top'),
path('home/', HomeView.as_view(), name='home'),
path('detail_medicine/', MedicineDetailView.as_view(), name='detail_medicine'),
path('list_medicines', MedicineListView.as_view(), name='list_medicines'),
path('list_medicines/', MedicineListView.as_view(), name='list_medicines'),
path('insert_medicine/', MedicineCreateView.as_view(), name='insert_medicine'),
path('update_medicine/', MedicineUpdateView.as_view(), name='update_medicine'),
path('delete_medicine/', MedicineDeleteView.as_view(), name='delete_medicine'),
path('form_medicine/', MedicineFormView.as_view(), name='form_medicine'),
path('shelokuma/', RedirectView.as_view(url='https://shelokuma.com')),
path('redirectview_medicine/', MedicineRedirectView.as_view(), name='redirectview_medicine'), # 追記箇所
]
ターミナルを開き,仮想環境に移行し,"cd class_based_view"のディレクトリにて,”python manage.py runserver”を実行する."http://127.0.0.1:8000/"をクリックすると,ブラウザが開くので,URLに"http://127.0.0.1:8000/ec_site/redirectview_medicine"と入力すると,以下ページ(https://shelokuma.com)に遷移する.
“ec_site/views.py"に追記し,以下のように編集する.
from django.shortcuts import render
from django.views.generic.base import (
View, TemplateView, RedirectView,
)
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import (
CreateView, UpdateView, DeleteView,
FormView,
)
from . import forms
import random
from .models import Medicines
from datetime import datetime
from django.urls import reverse_lazy
class TopView(View):
def get(self, request, *args, **kwargs):
medicine_form = forms.MedicineForm()
return render(request, 'top.html', context={
'medicine_form': medicine_form,
})
def post(self, request, *args, **kwargs):
medicine_form = forms.MedicineForm(request.POST or None)
if medicine_form.is_valid():
medicine_form.save()
return render(request, 'top.html', context={
'medicine_form': medicine_form,
})
class HomeView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['name'] = kwargs.get('name')
context['alphabet'] = random.randint(0,9999)
return context
class MedicineDetailView(DetailView):
model = Medicines
template_name = 'medicine.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['time'] = datetime.now()
return context
class MedicineListView(ListView):
model = Medicines
template_name = 'medicine_list.html'
def get_queryset(self):
qs = super(MedicineListView, self).get_queryset()
if 'name' in self.kwargs:
qs = qs.filter(name__startswith=self.kwargs['name'])
qs = qs.order_by('-id')
return qs
class MedicineCreateView(CreateView):
model = Medicines
fields = ['name', 'description', 'price']
template_name = 'insert_medicine.html'
def form_valid(self, form):
form.instance.create_time = datetime.now()
form.instance.update_time = datetime.now()
return super(MedicineCreateView, self).form_valid(form)
def get_initial(self, **kwargs):
initial = super(MedicineCreateView, self).get_initial(**kwargs)
initial['price'] = '1000'
return initial
class MedicineUpdateView(UpdateView):
template_name = 'update_medicine.html'
model = Medicines
form_class = forms.MedicineUpdateForm
class MedicineDeleteView(DeleteView):
model = Medicines
template_name = 'delete_medicine.html'
success_url = reverse_lazy('ec_site:list_medicines')
class MedicineFormView(FormView):
template_name = 'form_medicine.html'
form_class = forms.MedicineForm
success_url = reverse_lazy('ec_site:list_medicines')
def get_initial(self):
initial = super(MedicineFormView, self).get_initial()
initial['price'] = '2000'
return initial
def form_valid(self, form):
if form.is_valid():
form.save()
return super(MedicineFormView, self).form_valid(form)
class MedicineRedirectView(RedirectView):
url = 'https://shelokuma.com'
def get_redirect_url(self, *args, **kwargs): # 以下追記箇所
medicine = Medicines.objects.first()
return reverse_lazy('ec_site:update_medicine', kwargs={'pk': medicine.pk})
上記を保存し,ブラウザにて"http://127.0.0.1:8000/ec_site/redirectview_medicine"と入力すると,以下の編集ページ(pkが最大:最新ページ)に遷移する.
“ec_site/urls.py"に追記し,以下のように編集する.
from django.urls import path
from .views import (
TopView, HomeView, MedicineDetailView,
MedicineListView, MedicineCreateView,
MedicineUpdateView, MedicineDeleteView,
MedicineFormView, MedicineRedirectView,
)
from django.views.generic.base import RedirectView
app_name = 'ec_site'
urlpatterns = [
path('top/', TopView.as_view(), name='top'),
path('home/', HomeView.as_view(), name='home'),
path('detail_medicine/', MedicineDetailView.as_view(), name='detail_medicine'),
path('list_medicines', MedicineListView.as_view(), name='list_medicines'),
path('list_medicines/', MedicineListView.as_view(), name='list_medicines'),
path('insert_medicine/', MedicineCreateView.as_view(), name='insert_medicine'),
path('update_medicine/', MedicineUpdateView.as_view(), name='update_medicine'),
path('delete_medicine/', MedicineDeleteView.as_view(), name='delete_medicine'),
path('form_medicine/', MedicineFormView.as_view(), name='form_medicine'),
path('shelokuma/', RedirectView.as_view(url='https://shelokuma.com')),
path('redirectview_medicine/', MedicineRedirectView.as_view(), name='redirectview_medicine'),
path('redirectview_medicine/', MedicineRedirectView.as_view(), name='redirectview_medicine'), # 追記箇所
]
“ec_site/views.py"に追記し,以下のように編集する.
from django.shortcuts import render
from django.views.generic.base import (
View, TemplateView, RedirectView,
)
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import (
CreateView, UpdateView, DeleteView,
FormView,
)
from . import forms
import random
from .models import Medicines
from datetime import datetime
from django.urls import reverse_lazy
class TopView(View):
def get(self, request, *args, **kwargs):
medicine_form = forms.MedicineForm()
return render(request, 'top.html', context={
'medicine_form': medicine_form,
})
def post(self, request, *args, **kwargs):
medicine_form = forms.MedicineForm(request.POST or None)
if medicine_form.is_valid():
medicine_form.save()
return render(request, 'top.html', context={
'medicine_form': medicine_form,
})
class HomeView(TemplateView):
template_name = 'home.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['name'] = kwargs.get('name')
context['alphabet'] = random.randint(0,9999)
return context
class MedicineDetailView(DetailView):
model = Medicines
template_name = 'medicine.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['time'] = datetime.now()
return context
class MedicineListView(ListView):
model = Medicines
template_name = 'medicine_list.html'
def get_queryset(self):
qs = super(MedicineListView, self).get_queryset()
if 'name' in self.kwargs:
qs = qs.filter(name__startswith=self.kwargs['name'])
qs = qs.order_by('-id')
return qs
class MedicineCreateView(CreateView):
model = Medicines
fields = ['name', 'description', 'price']
template_name = 'insert_medicine.html'
# success_url = reverse_lazy('ec_site:list_medicines')
def form_valid(self, form):
form.instance.create_time = datetime.now()
form.instance.update_time = datetime.now()
return super(MedicineCreateView, self).form_valid(form)
def get_initial(self, **kwargs):
initial = super(MedicineCreateView, self).get_initial(**kwargs)
initial['price'] = '1000'
return initial
class MedicineUpdateView(UpdateView):
template_name = 'update_medicine.html'
model = Medicines
form_class = forms.MedicineUpdateForm
class MedicineDeleteView(DeleteView):
model = Medicines
template_name = 'delete_medicine.html'
success_url = reverse_lazy('ec_site:list_medicines')
class MedicineFormView(FormView):
template_name = 'form_medicine.html'
form_class = forms.MedicineForm
success_url = reverse_lazy('ec_site:list_medicines')
def get_initial(self):
initial = super(MedicineFormView, self).get_initial()
initial['price'] = '2000'
return initial
def form_valid(self, form):
if form.is_valid():
form.save()
return super(MedicineFormView, self).form_valid(form)
class MedicineRedirectView(RedirectView):
url = 'https://shelokuma.com'
def get_redirect_url(self, *args, **kwargs):
medicine = Medicines.objects.last()
if 'pk' in kwargs: # 追記箇所(110~111行目)
return reverse_lazy('ec_site:detail_medicine', kwargs={'pk':kwargs['pk']})
return reverse_lazy('ec_site:update_medicine', kwargs={'pk': medicine.pk})
上記を保存し,ブラウザにて"http://127.0.0.1:8000/ec_site/redirectview_medicine/"の後ろに数字を記載すると,以下のように詳細ページに遷移する.今回は"1″を入力した.
https://docs.djangoproject.com/ja/3.2/ref/class-based-views/base/#redirectview
以上