4

Это мое мнение:Как получить вид Django вернуть ошибки формы

def main_page(request): 

    if request.method == 'POST': 
     form = RegistrationForm(request.POST) 
     if form.is_valid(): 
      user = User.objects.create_user(
       username=form.clean_data['username'], 
       password=form.clean_data['password1'], 
       email=form.clean_data['email'] 
      ) 
     return HttpResponseRedirect('/') 
    else: 
     form = RegistrationForm() 
     variables = { 
      'form': form 
     } 
     return render(request, 'main_page.html', variables) 

и это мой main_page.html:

{% if form.errors %} 
    <p>NOT VALID</p> 
    {% for errors in form.errors %} 
     {{ errors }} 
    {% endfor %} 
{% endif %} 
<form method="post" action="/">{% csrf_token %} 
    <p><label for="id_username">Username:</label>{{ form.username }}</p> 
    <p><label for="id_email">Email Address:</label>{{ form.email }}</p> 
    <p><label for="id_password">Password:</label>{{ form.password1 }}</p> 
    <p><label for="id_retypePassword">Retype Password:</label>{{ form.password2 }}</p> 
    <input type="hidden" name="next" /> 
    <input type="submit" value="Register" /> 
</form> 

Когда я иду в URL, который использует вид main_page , он просто отображает форму. Когда я отправляю форму с ошибками (с пустыми полями и без надлежащего адреса электронной почты), она просто перенаправляет меня на ту же страницу и не отображает никаких ошибок. Он даже не говорит «НЕ ДЕЙСТВИТЕЛЬНО».

Когда я изменяю

{% if form.errors %} 

в

{% if not form.is_valid %} 

он всегда говорит «НЕ ДЕЙСТВУЕТ» (даже если это первый раз собирается в URL, и даже если я ничего не представить все же).

Это мой RegistrationForm:

from django import forms 
import re 
from django.contrib.auth.models import User 
from django.core.exceptions import ObjectDoesNotExist 

class RegistrationForm(forms.Form): 
    username = forms.CharField(label='Username', max_length=30) 
    email = forms.EmailField(label='Email') 
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput()) 
    password2 = forms.CharField(label='Password (Again)', widget=forms.PasswordInput()) 

    def clean_password2(self): 
     if 'password1' in self.cleaned_data: 
      password1 = self.cleaned_data['password1'] 
      password2 = self.cleaned_data['password2'] 
      if password1 == password2: 
       return password2 
     raise forms.ValidationError('Passwords do not match.') 

     def clean_username(self): 
     username = self.cleaned_data['username'] 
     if not re.search(r'^\w+$', username): #checks if all the characters in username are in the regex. If they aren't, it returns None 
      raise forms.ValidationError('Username can only contain alphanumeric characters and the underscore.') 
     try: 
      User.objects.get(username=username) #this raises an ObjectDoesNotExist exception if it doesn't find a user with that username 
     except ObjectDoesNotExist: 
      return username #if username doesn't exist, this is good. We can create the username 
     raise forms.ValidationError('Username is already taken.') 

ответ

8

Он перенаправляет вас, потому что вы всегда возвращаете HttpResponseRedirect, если метод POST, даже если форма не vaild. Попробуйте это:

def main_page(request): 
    form = RegistrationForm() 
    if request.method == 'POST': 
     form = RegistrationForm(request.POST) 
     if form.is_valid(): 
      user = User.objects.create_user(
       username=form.clean_data['username'], 
       password=form.clean_data['password1'], 
       email=form.clean_data['email'] 
      ) 
      return HttpResponseRedirect('/')   
    variables = { 
     'form': form 
    } 
    return render(request, 'main_page.html', variables) 

Таким образом, форма экземпляра, на котором is_valid был назван, передается в шаблон, и у него есть шанс, чтобы показать ошибки. Только если форма действительна, пользователь перенаправляется. Если вы хотите быть фантастическим, добавьте сообщение, используя messages framework перед перенаправлением.

Если вы хотите немного более кратким:

def main_page(request): 
    form = RegistrationForm(request.POST or None) 
    if form.is_valid(): 
     user = User.objects.create_user(
      username=form.clean_data['username'], 
      password=form.clean_data['password1'], 
      email=form.clean_data['email'] 
     ) 
     return HttpResponseRedirect('/')   
    variables = { 
     'form': form 
    } 
    return render(request, 'main_page.html', variables) 
+0

право, что я изначально имел, но что происходит «если request.method ==« POST », но форма недействительна? Ему все еще нужно что-то вернуть, верно? Я попробовал ваше представление, и он дает значение ValueError, если форма недействительна, ошибка говорит о том, что «представление main_page не возвратило объект HttpResponse». – user2719875

+0

из моего непонятного, я хотел, чтобы он всегда перенаправлялся на главную страницу, даже если форма недействительна, потому что тогда я смог бы правильно отображать ошибки в форме на главной странице? И если это действительно так, то это хорошо. Если это не так, все равно хорошо, потому что он перенаправляется на главную страницу с помощью form.errors. Это странно, потому что даже после того, как я нажал submit с ошибками формы (используя представление, которое я разместил), шаблон не отображает ошибки формы, так что это похоже на то, что представление не понимает, что request.method == 'POST'. – user2719875

+1

Ну, 'if request.method ==« POST »и' not form.is_valid', выполнение просто продолжается ниже и, наконец, возвращает результат функции «render», поэтому он должен работать ...? – sk1p

2

Сделайте вид что-то вроде этого:

if form.is_valid(): 
    pass 
    # actions 
else: 
    # form instance will have errors so we pass it into template 
    return render(request, 'template.html', {'form': form}) 

И в шаблонах вы можете перебрать form.errors или просто:

{{ forms.as_p }} 
+0

правильно, но есть также возможность, если request.method = «POST» (потому что это моя моя главная страница, так что если это первый время, когда пользователь просто обращается к главной странице, тогда он ничего не отправил, поэтому request.method! = «POST» правильно? – user2719875

+1

Да, метод запроса будет GET. Я рекомендую вам взглянуть на классы, основанные на классе django. быстрый пример проверки формы без грязного 'if request.method == POST' и т. д.: http://pastebin.com/D5YwFLpP Если пользователь открывает открытую страницу в первый раз, метод' get' будет отображать форму. Если пользователь отправит форму метода 'post' проверит его и предпримет соответствующие действия. – xelblch

Смежные вопросы