Django's UserCreationForm's Errors isn't working? - python

few months ago i made a website where it worked but similar code this time isn't working! it returns :
ValueError at /registration/
The User could not be created because the data didn't validate.
this is my form.py in bottom:
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ["username", "email", "password1", "password2"]
my views:
from .form import CreateUserForm
def registrationPage(request):
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid:
form.save()
return redirect("login")
else:
form = CreateUserForm()
context = {"form": form}
return render(request, "store/registration.html", context)
in HTML previously i used :
{{form.errors}}
& it used to show me work on the page but not anymore

According to your comment above ("i want django to show the error messages"[if password is weak in example]), you should add this to your html page (instead than {{form.errors}}).
<div class="error-message">
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p style="font-size: 13px;">
{{ error|escape }}
</p>
{% endfor %}
{% endif %}
</div>
Form.non_field_errors()
This method returns the list of errors from Form.errors that aren’t associated with a particular field. This includes ValidationErrors that are raised in Form.clean() and errors added using Form.add_error(None, "...").

When this error you get then do this:
You must type strong password, which is provided by Django.
password validation rules:
At least 1 digit;
At least 1 uppercase character;
At least 1 lowercase character;
At least 1 special character;
for example:
Example#4089
This error will come while confirming your password, you must enter correct password in both the fields.
you will face this error if user is already exist.
you must check exists user while creating user, if user exist, this error will come.

Related

How to display custom errors in the template

I have function with custom errors, how to display these errors in the template
def auth_join(request, room, slug):
if request.method == 'POST':
user = request.user.username
form_auth = AuthRoomForm(request.POST)
if form_auth.is_valid():
room_pass = form_auth.cleaned_data.get('room_pass')
password2 = form_auth.cleaned_data.get('password2')
if room_pass != password2:
messages.error(request, 'Doesn\'t match')
return HttpResponse('error')
else:
# messages.success(request, 'match')
user = CustomUser.objects.get(username=user)
room = get_object_or_404(Room, slug=slug)
if user.has_perm('pass_perm', room):
return HttpResponseRedirect(Room.get_absolute_url(room))
else:
return HttpResponse('You don\'t have access to this page')
else:
form_auth = AuthRoomForm()
return render(request,'rooms/auth_join.html', {'form_auth':form_auth})
I mean maybe try to do something like that,what i should use istead HttpResponse and how to implement in the template
{% if form_auth.errors %}
{% for field in form_auth %}
{% for error in field.errors %}
<div class="ui red message">
{{error}}
</div>
{% endfor %}
{% endfor %}
{% endif %}
You template is showing all the form's errors. So you just need to make sure that the validation errors are added to the form, and that's not done by returning an HttpResponse with just an error string.
You have two options:
Preferred route is to perform all validation in your form AuthRoomForm, not in your view. The documentation explains all the ways to add custom validation to your form, most common is to use the clean() and clean_<fieldname>() methods.
If you really want to do this in your view, just use the form.add_error() method, e.g. form.add_error(ValidationError('You don\'t have access to this page')).
In both cases, if the form isn't valid, don't return HttpResponse(<error>). Just render() your template with the bound form, as shown here and in every starter Django tutorial about Django forms.

Not able to redirect a Django form after submission

I am a newbie to Django and a form I created is giving me a bit of trouble.
I have create a form in Django for user authentication and login. But the form is not redirecting to the link I've specified after hitting submit. I think this is because the authentication function in views.py is returning the user as None. But this should not happen because the user exists in the database. I've confirmed this by going to http://127.0.0.1:8000/admin/, which is Django's internal developer server.
The URL that I'm trying to redirect it to exists. No problems there.
The python files related to this are:
forms.py:
from django.contrib.auth.models import User
from django import forms
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'email', 'password']
views.py:
I've omitted all the imports in the following code. No problems there.
class UserFormView(View):
form_class = UserForm
template_name = 'music/registration_form.html'
def get(self, request): # This function is executed if the server obtains a GET request.
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
'''
The server gets a GET request every time a new user wants to register, i.e they want an empty form.
That's why we pass None in the function above.
It gets a POST request every time a filled form is submitted.
'''
def post(self, request): # This function is executed if the sever recevies a POST request.
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False) # This creates an object, but does not save it to the database.
# Therefore, we can do some changes.
username = form.cleaned_data['username']
password = form.cleaned_data['password']
# Here, cleaned_data is converted data to suitable format. Like the date entered is converted to a
# suitable format as its format is different all around the world.
# Now you can change the username by user.username = 'some_name' or you can change the password by
# user.set_password(new_password)
user.save() # This line of code actually saves the code.
user = authenticate(username=username, password=password)
# This checks if the user actually exists in the database.
if user is not None:
if user.is_active: # This if the user is not banned or anything like that.
login(request, user) # This logs in the user.
return redirect('music:index') # Redirects the user to index page.
else:
return render(request, self.template_name, {'form': form})
else:
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
# This returns the filled form again if the the form is not valid.
The registration form template is (html file) :
{% extends 'music/base.html' %}
{% block title%}Registration Form {% endblock %}
{% block body %}
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'music/index_style.css' %}" />
<div class="block">
<form action="" method="post" >
{% csrf_token %}
<fieldset> <!-- Gives it a better look by putting a heading and background around the form -->
<legend>Create a new account:</legend><!-- This the common heading for the form -->
{% include 'music/form_template.html' %}
<br>
<input type="submit" value="Submit">
</fieldset>
</form>
</div>
{% endblock %}>
The form_template.html included in the registration form template is:
{{ form.non_field_errors }}
{{ form.errors }}
{{ form.as_p }}
Also, one other thing that is not normal is that whenever I create a new user by using the above form, the password for that user is being shown as:
"Invalid password format or unknown hashing algorithm."
This can be seen at http://127.0.0.1:8000/admin/ where we can edit the current users.
There are a few issues here.
You correctly call save with commit=False, to allow you to set the hashed password before saving properly (as the comments state), but you never actually do so, so the user is saved with an unhashed password. This will never validate.
Similarly, you never set the user's is_active property, so the check a bit further down will always fail.
user = form.save(commit=False)
password = form.cleaned_data['password']
user.set_password(password)
user.is_active = True
user.save()

Ensure this value has at most %(limit_value)d characters (it has %(show_value)d). -Django error

"Ensure this value has at most %(limit_value)d characters (it has
%(show_value)d)."
This is the error i get in my django form that i rendered using html when i post the data. I have defined no restrictions on my fields.
Form :
author = 'PRAYAS'
from django import forms
from login.models import UserProfile
class loginform(forms.ModelForm) :
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput())
fullname = forms.CharField(max_length=256)
class Meta :
model = UserProfile
fields = ('username','password','fullname')
<body>
{% if registered %}
<h1>Thanks For Registering!</h1>
{% else %}
<h1>Create new Account</h1>
<form id="form" method="post" action="/login/register/"
enctype="multipart/form-data">
{% csrf_token %}
<!-- Display each form. The as_p method wraps each element in a paragraph
(<p>) element. This ensures each element appears on a new line,
making everything look neater. -->
{{ form.as_p }}
<!-- Provide a button to click to submit the form. -->
<input type="submit" name="submit" value="Register" />
</form>
{% endif %}
</body>
</html>
def Register(request):
registered =False
if (request.method=='POST') :
user_form = loginform(data=request.POST)
try :
user = user_form.save()
user.set_password(user.password)
user.save()
registered=True
except :
print user_form.errors
return render(request,'login/register.html',{'form':user_form,'registered':registered,'slug':''})
if(request.method=='GET') :
user_form = loginform()
return render(request,'login/register.html',{'form':user_form,'registered':registered,'slug':''})
`
Never, ever, ever do a blank except.
Django forms have a means of triggering validation: form.is_valid(). You must always call that before attempting to call save. This is fully documented and there is no reason not to follow the exact pattern given there.

Populating Django Templates from retrieved records

I'm familar with using templates to collect the data, but on displaying is there a smart way that Django will display the fields and populate them with the right values. I can do it manually of course, but the model knows the field type. I didn't see any documentation on this. For example I collect data from the template with:
<strong>Company Name</strong>
<font color="red">{{ form.companyname.errors }}</font>
{{ form.companyname }}
where form is my company model containing all the fields. How would I go about ensuring that I could use this type of methodology such that Django would render the text fields and populate with the current values. For example is there a way to send in values in the following way:
myid = int(self.request.get('id'))
myrecord = Company.get_by_id(myid)
category_list = CompanyCategory.all()
path = os.path.join(os.path.dirname(__file__), 'editcompany.html')
self.response.out.write(template.render(path, {'form': myrecord, 'category_list': category_list}))
Can I do the same this with records and will the template populate with values sent in? Thanks
It sounds like you may be confused about the difference and proper usage of Form vs ModelForm
Regardless of which type of form you use, the templating side of forms stays the same:
Note: all of the values in your form (as long as its bound to POST or has an instance) will be prepopulated at render.
<form class="well" action="{% url member-profile %}" method="POST" enctype="multipart/form-data">{% csrf_token %}
<fieldset>
{{ form.non_field_errors }}
{{ form.display_name.label_tag }}
<span class="help-block">{{ form.display_name.help_text }}</span>
{{ form.display_name }}
<span class="error">{{ form.display_name.errors }}</span>
{{ form.biography.label_tag }}
<span class="help-block">{{ form.biography.help_text }}</span>
{{ form.biography }}
<span class="error">{{ form.biography.errors }}</span>
<input type="submit" class="button primary" value="Save" />
</fieldset>
</form>
if you want to be populating a form from a record (or submit a form as a record) its probably best to use ModelForm
EX a profile form that doesn't display the User FK dropdown:
class ProfileForm(forms.ModelForm):
"""Profile form"""
class Meta:
model = Profile
exclude = ('user',)
The View:
def profile(request):
"""Manage Account"""
if request.user.is_anonymous() :
# user isn't logged in
messages.info(request, _(u'You are not logged in!'))
return redirect('member-login')
# get the currently logged in user's profile
profile = request.user.profile
# check to see if this request is a post
if request.method == "POST":
# Bind the post to the form w/ profile as initial
form = ProfileForm(request.POST, instance=profile)
if form.is_valid() :
# if the form is valid
form.save()
messages.success(request, _(u'Success! You have updated your profile.'))
else :
# if the form is invalid
messages.error(request, _(u'Error! Correct all errors in the form below and resubmit.'))
else:
# set the initial form values to the current user's profile's values
form = ProfileForm(instance=profile)
return render(
request,
'membership/manage/profile.html',
{
'form': form,
}
)
notice that the outer else initializes the form with an instance: form = ProfileForm(instance=profile) and that the form submit initializes the form with post, BUT still binds to instance form = ProfileForm(request.POST, instance=profile)
If you're looking at forms, it would seem like a good idea to start with Django's forms framework, specifically forms for models.

Django Model Formsets and named urls

I'm having some problems with model formsets in django.
# forms.py
OppFormSet = modelformset_factory(Opportunity, fields=opp_fields)
# views.py
def index2(request):
queryset = Opportunity.objects.for_user(request.user).filter(is_deleted=False)
if request.method == 'POST':
formset = OppFormSet(request.POST, queryset=queryset)
else:
formset = OppFormSet(queryset=queryset)
return render_to_response("opp_index2.tmpl", { "formset" : formset}, context_instance=RequestContext(request))
Here are my 2 questions regarding model forms:
In my template I have {% for form in formset %} to create the forms in a table, but somehow, I keep getting an extra blank row, as if there is an additional blank form in the formset.
If i use {{ form.instance.id }} to output an id while iterating through the formset, it prints out ok. However, if I do a {% url summary form.instance.id %} I keep getting an error regarding no NoReverseMatch with arguments (None,). It seems like when using form.instance.id in a template tag, it doesn't work. Is that true? If so, how do i circumvent it?
Thank you in advance.
Use {% for form in formset.forms %} This "blank form" is ManagementForm

Categories

Resources