Python | Django | エラー改善 | フォームにおける入力値が出力しない

2021年7月8日

公開日:2021/7/8

Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.

フォームにおけるバリデーションの使い方」で起きたエラー改善を以下3つの構成にて記す.なお,結論は,クラスメソッドの名前を「clean_chocolate_name」にすると値を渡せないエラーが発生したが,名前を「clean_chocolatename」にすると値を渡せるようになった.

  1. エラー改善前
  2. エラー改善後
  3. 結論

※クラスメソッドの名前について,「clean_chocolate_name」以外に様々な類似の名前を入力してみたが全てにおいてエラーは発生しなかった.そのため,原因がわからなかった.

◆実施環境

Python 3.8.8
Django 3.2.3

■エラー改善 | フォームにおける入力値が出力しない

  1. エラー改善前

以下ページ(“http://127.0.0.1:8000/form_application/form_page/")でチョコレート名に入力制限をかけることを目的とした.

“form_app/forms.py"に追記し,以下のように編集する.チョコレート名を入力する際,"F"から始めないとエラーが出るようなコードを追記した.

from django import forms

class ChocolateInfo(forms.Form):
  chocolate_name = forms.CharField(label='チョコレート名', max_length=50)
  chocolate_maker = forms.CharField(label='チョコレートメーカー', max_length=50)
  mail = forms.EmailField(label='メールアドレス')
  is_available_for_sale = forms.BooleanField(label='販売中')
  birthday = forms.DateField(required=False, label='開発日')
  price = forms.DecimalField(initial=300, max_value=1000, label='価格')
  
  flavor = forms.ChoiceField(choices=(
    (1,'Original Chocolat'),
    (2,'Double Chocolat'),
    (3,'Original White'),
    (4,'Rich Matcha'),
  ), widget=forms.RadioSelect, label='味')
  
  maker_factory = forms.MultipleChoiceField(choices=(
    (1,'Ibaraki Moriya-city'),
    (2,'Saitama Sakado-city'),
    (3,'Aichi Inazawa-city'),
    (4,'Osaka Takatsuki-city'),
  ), widget=forms.CheckboxSelectMultiple, label='メーカー工場')
  
  homepage = forms.URLField(
    label='ホームページ',
    widget=forms.TextInput(attrs={'class':'url_class','placeholder':'https://www.shelokuma.com'})
  )

def __init__(self,*args,**kwargs):
  super(ChocolateInfo, self).__init__(*args,**kwargs)
  self.fields['flavor'].widget.attrs['id']='id_flavor'
  self.fields['maker_factory'].widget.attrs['class']='maker_factory_class'

def clean_chocolate_name(self): # 以下追記箇所
  chocolate_name = self.cleaned_data['chocolate_name']
  if not chocolate_name.startswith('F'):
      raise forms.ValidationError('名前は「F」から始めてください')

以下ページ(“http://127.0.0.1:8000/form_application/form_page/")で各項目に値を入力し,"submit"をクリックした.

ターミナルには,以下のように上記で入力した内容が出力された."chocolate_name: None"がエラーとして出力された.

submission is successful
{'chocolate_name': None, 'chocolate_maker': 'Meiji', 
'mail': 'Faaa@gmail.com', 'is_available_for_sale': True, 
'birthday': datetime.date(1999, 1, 1), 'price': Decimal('300'), 
'flavor': '3', 'maker_factory': ['1', '2'], 
'homepage': 'https://www.google.com'}
  1. エラー改善後

“form_app/forms.py"に追記し,以下のように編集する.メソッド名を"clean_chocolate_name"から"clean_chocolatename"にした.

from django import forms

class ChocolateInfo(forms.Form):
  chocolate_name = forms.CharField(label='チョコレート名', max_length=50)
  chocolate_maker = forms.CharField(label='チョコレートメーカー', max_length=50)
  mail = forms.EmailField(label='メールアドレス')
  is_available_for_sale = forms.BooleanField(label='販売中')
  birthday = forms.DateField(required=False, label='開発日')
  price = forms.DecimalField(initial=300, max_value=1000, label='価格')
  
  flavor = forms.ChoiceField(choices=(
    (1,'Original Chocolat'),
    (2,'Double Chocolat'),
    (3,'Original White'),
    (4,'Rich Matcha'),
  ), widget=forms.RadioSelect, label='味')
  
  maker_factory = forms.MultipleChoiceField(choices=(
    (1,'Ibaraki Moriya-city'),
    (2,'Saitama Sakado-city'),
    (3,'Aichi Inazawa-city'),
    (4,'Osaka Takatsuki-city'),
  ), widget=forms.CheckboxSelectMultiple, label='メーカー工場')
  
  homepage = forms.URLField(
    label='ホームページ',
    widget=forms.TextInput(attrs={'class':'url_class','placeholder':'https://www.shelokuma.com'})
  )

def __init__(self,*args,**kwargs):
  super(ChocolateInfo, self).__init__(*args,**kwargs)
  self.fields['flavor'].widget.attrs['id']='id_flavor'
  self.fields['maker_factory'].widget.attrs['class']='maker_factory_class'

def clean_chocolate_name(self): # 以下追記箇所
  chocolate_name = self.cleaned_data['chocolate_name']
  if not chocolate_name.startswith('F'):
      raise forms.ValidationError('名前は「F」から始めてください')

再度,以下ページ(“http://127.0.0.1:8000/form_application/form_page/")で各項目に値を入力し,"submit"をクリックした.

ターミナルには,以下のように上記で入力した内容が出力された."chocolate_name: Faaa"が出力された.

submission is successful
{'chocolate_name': 'Faaa', 'chocolate_maker': 'Meiji', 
'mail': 'Faaa@gmail.com', 'is_available_for_sale': True, 
'birthday': datetime.date(1999, 1, 1), 'price': Decimal('300'), 
'flavor': '3', 'maker_factory': ['1', '2'], 
'homepage': 'https://www.google.com'}
  1. 結論

バリデーション向けに,クラスメソッドの名前を「clean_chocolate_name」にすると値を渡せないエラーが発生したが,名前を「clean_chocolatename」にすると値を渡せるようになった.

改善前:クラスメソッドの名前を「clean_chocolate_name」にした

改善後:クラスメソッドの名前を「clean_chocolatename」にした

※「clean_chocolate_name」以外に様々な類似の名前を試してみたが全てにおいてエラーは発生しなかった.そのため,原因がわからなかった.

以上