質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1425閲覧

[Django]バリデーションチェック失敗時のソースコード

pigton

総合スコア47

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/10/12 01:53

編集2018/10/12 05:07

前提・実現したいこと

Python: 3.6.6
Django: 2.1

現在、ログイン機能をバリデーションチェックの学習をしています。

ユーザ名を2文字までしか入れなかった場合、clean_username()でValidationErrorをraiseするようにしているのですが、
その後のclean() のusername = self.cleaned_data['username']で
「'username'がない」と言われてしまいます。
バリデーションNGの値は'cleaned_data' に値が再セットされないので当然のことだと思います。

この解決法ですが、以下の記述をclean()の頭に追加し、

python

1 if self.errors: 2 return

エラーがある場合は return clean() のバリデーションチェックを行わないという方法を考えています。

この方法で大丈夫でしょうか?
ネットで検索しても、このような記述をされている方がおらず、あまり良くない方法なのかと不安です。

皆様の思う、最善の方法を踏まえてご回答頂けると幸いです。

回答よろしくお願い致します。

該当のソースコード

*accounts/views.py

Python

1from django.contrib.auth.views import LoginView as AuthLoginView 2from django.shortcuts import render, redirect 3from django.urls import reverse 4 5from .forms import LoginForm 6 7 8class LoginView(AuthLoginView): 9 def post(self, request, *args, **kwargs): 10 form = LoginForm(request.POST) 11 is_valid = form.is_valid() 12 13 if not is_valid: 14 return render(request, 'accounts/login.html', {'form': form}) 15 16 return redirect(reverse('shop:book_list')) 17 18 def get(self, request, *args, **kwargs): 19 form = LoginForm() 20 return render(request, 'accounts/login.html', {'form': form}) 21 22 23# accounts/urls.py でURLディスパッチャされてくる 24login = LoginView.as_view()

*accounts/forms.py

Python

1from django import forms 2from django.contrib.auth.forms import UsernameField 3from django.core.exceptions import ObjectDoesNotExist 4 5from .models import CustomUser 6 7 8class LoginForm(forms.Form): 9 """ログイン画面用のフォーム""" 10 username = UsernameField( 11 label='ユーザ名', 12 max_length=255, 13 ) 14 15 password = forms.CharField( 16 label='パスワード', 17 strip=False, 18 widget=forms.PasswordInput(render_value=True), 19 ) 20 21 def clean_username(self): 22 # 入力値は cleaned_data から取得 23 username = self.cleaned_data['username'] 24 # 入力値が3桁より短ければバリデーションエラー 25 if len(username) < 3: 26 raise forms.ValidationError( 27 '%(min_length)s文字以上で入力してください', params={'min_length': 3} 28 ) 29 return username 30 31 def clean(self): 32 username = self.cleaned_data['username'] # ここでエラー 33 password = self.cleaned_data['password'] 34 try: 35 user = CustomUser.objects.get(username=username) 36 except ObjectDoesNotExist: 37 raise forms.ValidationError("正しいユーザ名を入力してください") 38 if not user.password == password: 39 print(password) 40 raise forms.ValidationError("正しいパスワードを入力してください") 41

発生している問題・エラーメッセージ

KeyError at /accounts/login/ 'username' Request Method: POST Request URL: http://localhost:8000/accounts/login/ Django Version: 2.1 Exception Type: KeyError Exception Value: 'username' Exception Location: /root/mysite2/mysite2/accounts/forms.py in clean, line 32 Python Executable: /usr/local/bin/python3 Python Version: 3.6.6 Python Path: ['/root/mysite2/mysite2', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/usr/local/lib/python3.6/site-packages'] Server time: Fri, 12 Oct 2018 01:15:23 +0000

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Meganezaru

2018/10/12 04:59

Viewの処理はどうなっていますか?
guest

回答1

0

ベストアンサー

フィールドのバリデーションがエラーになっているのであれば、少なくともis_validはfalseになるので、
ご検討された方法でも問題はなさそうですね。

cleaned_dataから値を取り出せなければ中断という処理でも良いかもしれませんね。

cleaned_dataから値を取り出す際、get()をつかうと例外が出ないので、扱いやすいかもしれません。

Django

1 username = self.cleaned_data.get('username')

投稿2018/10/12 05:35

Meganezaru

総合スコア715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pigton

2018/10/12 07:46

回答ありがとうございます! get()をつかうと例外が出ないのですね。大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問