異なるボタンによるPOSTのテストについて
tutorial/urls.py
"""tutorial URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/2.2/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: path('', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('tutorial/', include('tutorial_app.urls')), ]
tutorial_app/url.py
from tutorial_app.views import SampleFormView, SampleTemplateView from django.urls import path urlpatterns = [ #ここで、class_Viewを用いるときには、as_viewという表現を用いる。 path('template_index', SampleTemplateView.as_view()), path('sample_template', SampleFormView.as_view()), ]
models.py
from django.db import models class Product(models.Model): code = models.CharField('商品番号', max_length=30, unique=True) name = models.CharField('商品名', max_length=100) def __str__(self): return "{0}{1}".format(self.code, self.name)
forms.py
from django import forms from django.core import validators from . import models class ProductForm(forms.Form): name = forms.ModelChoiceField( models.Product.objects, label='商品', to_field_name='code' ) product = forms.CharField( required=False, validators=[validators.MaxLengthValidator(10)]) # clean_product関数 def clean_product(self): product = self.cleaned_data['product'] if len(product) > 5: raise forms.ValidationError("productのエラー") return product # clean関数 def clean(self): clean_data = super().clean() return clean_data
views.py
from django.views.generic import FormView, TemplateView from tutorial_app.forms import ProductForm from tutorial_app.models import Product class SampleFormView(FormView): form_class = ProductForm template_name = "tutorial_app/sample.html" success_url = "sample_template" def form_valid(self, form): print(form) return super().form_valid(form) def post(self, request, *args, **kwargs): if request.POST.get('action')=='送信1': print('送信1') if request.POST.get('action')=='送信2': print('送信2') return super().post(request, *args, **kwargs) class SampleTemplateView(TemplateView): template_name = "index.html"
sample.html
<html> <body> <form action="" method="post"> {% csrf_token %} {% if form.errors %} {% for errors in form.errors.values %} {% for error in errors %} {{ error }}<br> {% endfor %} {% endfor %} {% endif %} {% for field in form %} <div> {{ field.label_tag }} </div> <div> {{ field }} </div> {% endfor %} <button type="submit" name="action" value="送信1">送信1</button> <button type="submit" name="action" value="送信2">送信2</button> </form> </body> </html>
このようなテストが書ける。
from django.test import TestCase from django.test.client import Client class SubmitTests(TestCase): def test_submit(self): c = Client(enforce_csrf_checks=False) response1 = c.post('/tutorial/sample_template', {'name': '1', 'product': '車', 'action': '送信2'}) response2 = c.post('/tutorial/sample_template', {'name': '2', 'product': '馬', 'action': '送信1'}) self.assertEqual(response1.status_code, 200)
ここで、Clientメソッドは、Client()でもデフォルトでscrfがオフになっているのでcsrfについては設定する必要はない。 異なるボタンに反応させるには、dic型でボタンの名前と値を指定すれば良いとわかった。