On a website that I’m working on for my school, the user enters their school email and password, and if they have registered they log in. If not, a second part of the log in is revealed asking for a pen name and to confirm the password. Because of this, and my convoluted amateur Django programming, I have a list of errors named er. For instants, when the program tests whether the email is a school one, it might add to the er list “school email only”. I am also using two form classes as well. The page uses ajax to call this function, which uses plain html instead of JSON because of the sites small size.
In the forms.py file I have:
class log_in(forms.Form):
username = forms.EmailField(error_messages= {'required': "Email Field is required,", 'invalid' : "Invalid Email Address."})
password = forms.CharField(help_text = 'Password Invalid')
class new_user(forms.Form):
username = forms.EmailField(error_messages = {'required': "Email Field is required,", 'invalid' : "Invalid Email Address."})
password = forms.CharField(required=True)
password2 = forms.CharField(required=True)
pen_name = forms.CharField(max_length=30, min_length=3, error_messages = {'required': "Pen Name is required", 'max_length': "Pen Name must be less than 30 characters", 'min_length': "Pen Name must be more than 3 characters"})
The problem is that I want to transfer the full error message that I specified in the error_message argument to the er list.
This is my views.py file
def user_log_in(request):
er = []
user_pass = log_in(request.POST)
if user_pass.is_valid(): # If it is valid at all
cleaned_info = user_pass.cleaned_data
email_bbn = cleaned_info['username'].split("@")
if 'bbns.org' in email_bbn: # Check if BBN email address
user_object = User.objects.filter(email = cleaned_info['username'])
if user_object.exists():
logged_in_user = auth.authenticate(username=cleaned_info['username'], password=cleaned_info['password'])
#add in is_active
if logged_in_user is not None: #If password is right
if user_object[0].get_profile().activated:
auth.login(request, logged_in_user)
return HttpResponseRedirect("")
else:
return HttpResponse("not_act")
else:
er.append("Incorrect Password")
else: # If new user
new_user_pass = new_user(request.POST)
if new_user_pass.is_valid():
cleaned_info_new = new_user_pass.cleaned_data
if cleaned_info_new['password'] == cleaned_info_new['password2']:
msg = "In order to activate your account at Knights of the Round Table, please click on this link:"
try:
send_mail('Activate', msg, 'michaelrgoldfine@gmail.com', [cleaned_info_new['username']], fail_silently=False)
new_user_object = User.objects.create_user(
username=cleaned_info_new['username'],
password=cleaned_info_new['password'],
email=cleaned_info_new['username']
)
new_user_profile = new_user_object.get_profile()
new_user_profile.pen_name = cleaned_info_new['pen_name']
new_user_profile.activated = False;
new_user_profile.save()
return HttpResponse("not_act")
except:
er.append("Error Sending Email")
else:
er.append('Passwords are not the same')
elif "TN" in request.POST: #If open but not filled in
print "TN"
er.append(new_user_pass.pen_name.error_messages)
else: # if new user field
print "n_usr"
return HttpResponse('n_usr')
else:
er.append("BBN email addresses only")
else:
for e in user_pass.errors:
er.append(e)
errors_template = Template("{% for e in errors %}<li>{{ e }}</li> {% endfor %}")
errors_html = errors_template.render(Context({'errors':er}))
return HttpResponse(errors_html)
I try to accsess the errors twice. Once, on the else you see right at the end with a for loop, and two elses up from that on elif 'TN'... The last one just returns the field thats invalid (so i get user_name or pen_name). The other one says that the form has no object pen_name or whatever I use it for.
It would be better to add errors to the actual form. Forms have an
_errorsdict attached to them that contain all the errors generated by the form. “Non-field errors” (errors that don’t directly relate to a particular field or that relate to multiple fields) go inform._errors['__all__']. All field-specific errors go into the key of the field’s name. So, errors for afoofield would go inform._errors['foo'].Now, the list of errors for each item in the
_errorsdict is actually anErrorListtype, not a standard list. So, to add errors to the form you do:Or, to add the error to non-field errors:
Then, when your form renders, the errors will all fall naturally where they should, just like any normal validation error.