登録アプリを作成します。登録アプリでは、ユーザー名、メールアドレス、パスワードを入力して登録できます。私がやったことは、電子メールフィールドが一意であることを確認することです(以下のコードで確認できます)。しかし、ユーザーが既に使用されている電子メールアドレスを入力した場合に、どのようにエラーを表示できるかわかりません。
from Django.shortcuts import render
from Django.shortcuts import render_to_response
from Django.http import HttpResponseRedirect
from Django.core.context_processors import csrf
from forms import RegistrationForm
# Create your views here.
def register_user(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('../../membership/register_success')
else:
return HttpResponseRedirect('../../membership/register_failed')
args = {}
args.update(csrf(request))
args['form'] = RegistrationForm()
return render(request,'registration/registration_form.html', args)
def register_success(request):
return render_to_response('registration/registration_success.html')
def register_failed(request):
return render_to_response('registration/registration_failed.html')
from Django import forms
from Django.contrib.auth.models import User
from Django.contrib.auth.forms import UserCreationForm
from Django.utils.translation import ugettext_lazy as _
# forms.py
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(username=username).count():
raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
return email
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
{% extends "base.html" %}
{% block title %}Registration{% endblock %}
{% block content %}
<h1>Registration</h1>
{% if form.errors %}
<h1>ERRORRRRRR same email again???</h1>
{% endif %}
{% if registered %}
<strong>thank you for registering!</strong>
<a href="../../">Return to the homepage.</a><br />
{% else %}
<strong>register here!</strong><br />
<form method="post" action="/membership/register/">{% csrf_token %}
{{ form }}
<input type="submit" name="submit" value="Register" />
</form>
{% endif %}
{% endblock %}
テンプレートに_{{ form }}
_を含むフォームを表示しています。それ自体はデフォルトですべての検証エラーを表示するはずですが、あなたの場合、フォームが無効な場合は他のページにリダイレクトしています。したがって、GETパラメーターでエラーを渡さない限り、エラーを表示することはできません。ビューをこれに変更して、サインアップページ自体のエラーを取得できます-
_def register_user(request):
args = {}
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('../../membership/register_success')
else:
form = RegistrationForm()
args['form'] = form
return render(request,'registration/registration_form.html', args)
_
これがどのように機能するかは、リクエストメソッドがPOSTである場合、フォームはPOST= dataで開始され、is_valid()
呼び出しで検証されるため、フォームオブジェクトは有効な場合は検証エラーメッセージ、有効な場合は保存およびリダイレクトされます。有効でない場合は、エラーメッセージを含むフォームオブジェクトがコンテキストに設定され、レンダリングに渡される_args['form'] = form
_部分になります。
要求メソッドがPOSTでない場合、データのないフォームオブジェクトがインスタンス化され、render()
に渡されます。
これで、エラーが発生した場合、テンプレートの各フィールドのすぐ下にすべてのエラーメッセージが表示されます。
forms.py
from Django import forms
class RegistForm(forms.Form):
name = forms.CharField(required=True)
email = forms.EmailField(required=True)
password = forms.CharField(required=True)
views.py
from Django.shortcuts import render
from Django.views.generic import TemplateView
import forms
class Register(TemplateView):
def get(self, request):
return render(request, 'register.html', {})
def post(self, request):
form = forms.RegistForm(request.POST)
if form.is_valid():
print(1)
else:
print(form.errors)
content = {'form':form};
return render(request, 'register.html', content)
register.html
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
<fieldset>
<label for="name">Name:</label>
<input type="text" id="name" name="name" value="">
{{ form.errors.name }}
<label for="mail">Email:</label>
<input type="text" id="mail" name="email">
{{ form.errors.email }}
<label for="password">Password:</label>
<input type="password" id="password" name="password">
{{ form.errors.password }}
</fieldset>
<button type="submit">Sign Up</button>
<p class="message">Already registered? <a href="{% url 'login' %}">Login</a></p>
</form>
**コードをコピーしてお楽しみください! **
なぜこのようなことをしないのですか:
_...
if User.objects.filter(email=email):
raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
return email
...
_
ユーザーがすでに登録されている場合は、検証エラーを発生させます。これを実行したくない場合は、次のようなことができます:
_...
email_exists = User.objects.filter(email=email):
if email_exists and email_exists.username != username:
raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
return email
...
_
フォームエラーを表示するには、form.is_valid()
を使用して、検証に合格したことを確認します。 Djangoは、 カスタム検証 :
Note that any errors raised by your Form.clean() override will not be associated with any field in particular. They go into a special “field” (called __all__), which you can access via the non_field_errors() method if you need to. If you want to attach errors to a specific field in the form, you need to call add_error().
次に、テンプレートで_{{ form.non_field_errors }}
_などのようなものを使用できます。
_Using a form in a view
_および_Customizing the form template
_の下のDjango docs)のこのセクションを参照してください。
https://docs.djangoproject.com/en/dev/topics/forms/
クラスベースのビューは簡単です。
from Django.views import generic
from .forms import RegistrationForm
class RegistrationView(generic.CreateView):
template_class = 'registration/registration_form.html'
form_class = RegistrationForm
success_url = '/success/url'
def form_valid(self, form):
# add a log after save or whatever
super(RegistrationView, self).form_valid(self, form)
クリーンなメソッドは、フォームとメッセージがそのようにレンダリングされるので自動的に行われ、クラスベースのビューは非常に簡単になり、コードはより乾燥します。