how to resolve 'ValidationError' object has no attribute 'strip' issue?

Viewed 706

I want to add or raise a validation registration form but I get this error: 'ValidationError' object has no attribute 'strip' how can I skip it?

I'm suffering from these issues please if you could tell me the correct way to validate the registration form after you solve this problem I'll be appreciated. Thank you in advance

class SignUp(UserCreationForm):
    def __init__(self, *args, **kwargs):
        super(SignUp, self).__init__(*args, **kwargs)

        self.error_messages = {
            'username_match': 'username is already exist',
            'email_match': 'Email is already exist',
            'password_mismatch': 'these two password isn\'t match try again'
        }
    email = forms.EmailField(required=True)
    first_name = forms.CharField(required=True)
    last_name = forms.CharField(required=True)
    # password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
    # password2 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password'}))

    class Meta:
        model = User
        fields = ['username',
                  'first_name',
                  'last_name',
                  'password1',
                  'password2',
                  'email']

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            return forms.ValidationError(
                self.error_messages['email_match'],
            )
        return email

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if User.objects.filter(username=username).exists():
            return forms.ValidationError(
                self.error_messages['username_match'],
            )
        return username

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            return forms.ValidationError(
                self.error_messages['password_mismatch'],
            )
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

views.py

def register(request):
    form = SignUp(None)
    if request.method == 'POST':
        form = SignUp(request.POST)
        if form.is_valid():
            form.save()
            return redirect('accounts:login')
        return form.errors
    return render(request, 'accounts/register.html', {'form': form})

Edit with a new issue:

Traceback (most recent call last):
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al3/website/accounts/views.py", line 73, in register
    return render(request, 'accounts/register.html', {'form': form})
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/shortcuts.py", line 19, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/template/base.py", line 168, in render
    with context.bind_template(self):
  File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__
    return next(self.gen)
  File "/media/medo/BE4C6BE74C6B98C3/Cources/Django/all git/Django projects/Es2al/Es2al2/website/venv/lib/python3.8/site-packages/django/template/context.py", line 244, in bind_template
    updates.update(processor(self.request))

Exception Type: ValueError at /accounts/register/
Exception Value: dictionary update sequence element #0 has length 207; 2 is required

urls.py

urlpatterns = [
    path('register/', views.register, name='register'),
]
1 Answers

You should not return a ValidationError, but raise it. By returning it, the Form assumes that the result of username, etc. are ValidationErrors:

def clean_email(self):
    email = self.cleaned_data.get('email')
    if User.objects.filter(email=email).exists():
        raise forms.ValidationError(  # ← raise instead of return
            self.error_messages['email_match'],
        )
    return email

This principle should be applied to all the clean_… methods.

In your view, you can furthermore not return form.errors, or at least not direclty, you can print the form.errors, and pass these to a context, but a view should return a HttpResponse object:

def register(request):
    form = SignUp()
    if request.method == 'POST':
        form = SignUp(request.POST)
        if form.is_valid():
            form.save()
            return redirect('accounts:login')
        # return form.errors
    return render(request, 'accounts/register.html', {'form': form})
Related