1
votes

Django does not raise validation errors added to forms.py for username and password. It does bring up validation errors for password based on the core password validation, but will not check if passwords are the same. This is all based on the base User model in Django.

Can you help me figure out why the forms validation does not work? I get the following error is username is already in use or passwords do not match: "Form is not valid." The if statement if form.is_valid(): fails.

Forms.py:

class CustomUserCreationForm(forms.ModelForm):
    username = forms.CharField(label='Username', widget=forms.TextInput(attrs={'class': "form-control"}))
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput(attrs={'class': "form-control"}))
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput(attrs={'class': "form-control"}))

    class Meta:
        model = User
        fields = ['username']

    def clean_password(self):
        password1 = self.cleaned_data.get('password1')
        password2 = self.cleaned_data.get('password2')
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords do not match")
        return password2

    def clean_username(self):
        username = self.cleaned_data.get('username')
        user_name = User.objects.filter(username=username)
        if user_name.exists:
            raise forms.ValidationError("Username already exists. Please try again.")
        return username

    def save(self, commit=True):
        user = super(CustomUserCreationForm, self).save(commit=False)
        user.username = self.cleaned_data['username']
        user.set_password(self.cleaned_data['password1'])

        if commit:
            user.save()
        return user

Views.py:

def payments(request):
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            password1 = form.cleaned_data['password1']
            #this works to do Django core validation, but not form validation
            try:
                validate_password(password1)
            except ValidationError as e:
                form.add_error('password1', e) # to be displayed with the field's errors
            username = form.cleaned_data['username']
            #this does not work
            try:
                validate_username(username)
            except ValidationError as e:
                form.add_error('username', e)
            user = form.save(commit=False)
            user.is_active = True
            user.set_password(form.cleaned_data['password1'])
            user.save()          
        else:
            raise ValidationError("Form is not valid. Try Again.")
            return render(request, 'next.html', {'form': form})

    else:
        form = CustomUserCreationForm()
return render(request, 'next.html', {'form': form})

Template

<div class="col-md-6 mb-4">
                <h3 class="font-weight-bold">Register now</h3>
                <div class="card">
                    <div class="card-body">
                        <p>Already have an account? <a href="{% url 'login' %}"> Login</a></p>
                        <form method="POST" class="post-form">
                            {% csrf_token %}
                            {{ form }}
                            <div class="text-center mt-4">
                                <button type="submit" class="btn btn-secondary">Register</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
1
How are you rendering it in the template? - Matthew Gaiser
@Matthew added the template. - user11846186

1 Answers

0
votes

Most of that code is unnecessary. You should not be raising validation errors in your view; all the validation is already being done in the form. Your view should just be:

def payments(request):
    if request.method == "POST":
        form = CustomUserCreationForm(request.POST)
        if form.is_valid():
            password1 = form.cleaned_data['password1']
            user = form.save(commit=False)
            user.is_active = True
            user.set_password(form.cleaned_data['password1'])
            user.save()
            return redirect("/")
    else:
        form = CustomUserCreationForm()
    return render(request, 'next.html', {'form': form}

and you can display any errors in the template via {{ form.errors }}.