Reputation: 11
I have a RegisterForm that inherits from ModelForm with RegisterView that inherits from FormView. If every field data is valid, the user gets successfully created and is redirected to login page. But if there is a validation error, it shows the field error below that field and the form gets refreshed and all the fields data is lost. How to avoid form refreshing so that user need not to fill the details again and again.
forms.py
class RegisterForm(forms.ModelForm, PasswordValidatorMixin):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField( label='Confirm password', widget=forms.PasswordInput)
class Meta:
model = UserModel
fields = (
'first_name',
'last_name',
'username',
'password1',
'password2',
'current_email',
)
def __init__(self, social_email=None, social_fname=None, social_lname=None,
social_uname=None,*args, **kwargs):
super(RegisterForm, self).__init__(*args, **kwargs)
self.current_email = None
self.social_email = social_email
self.social_fname = social_fname
self.social_lname = social_lname
self.social_uname = social_uname
def clean(self, *args, **kwargs):
username = self.cleaned_data.get('username')
self.current_email = self.cleaned_data.get('current_email')
if self.social_email:
self.current_email = self.social_email
if not username:
raise forms.ValidationError({"username":"Username can't be empty"})
if not self.current_email:
raise forms.ValidationError({"current_email":"Email can't be empty"})
qs = UserModel.objects.filter(username=username)
qs_email = UserModel.objects.filter(current_email=self.current_email)
if qs.exists():
raise forms.ValidationError({"username":"Username is already taken"})
if qs_email.exists():
raise forms.ValidationError({"current_email":"Email has already been registered"})
return self.cleaned_data
def save(self, commit=True):
user = super().save(commit=False)
current_email = self.cleaned_data.get('current_email')
password = self.cleaned_data.get('password1')
user.set_password(password)
if self.social_email:
user.is_active = True
user.save()
return user
views.py
class RegisterView(ContextMixin, FormView):
form_class = RegisterForm
template_name = 'accounts/register.html'
title = 'Register'
@method_decorator(sensitive_post_parameters('password'))
@method_decorator(csrf_protect)
@method_decorator(never_cache)
def dispatch(self, *args, **kwargs):
self.kwargs['social_email'] = SOCIAL_USER_EMAIL
self.kwargs['social_fname'] = SOCIAL_USER_FNAME
self.kwargs['social_lname'] = SOCIAL_USER_LNAME
if SOCIAL_USER_EMAIL:
self.kwargs['social_uname'] = SOCIAL_USER_EMAIL.split('@',1)[0]
return super(RegisterView, self).dispatch(*args, **kwargs)
# Passes view kwargs to html
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if SOCIAL_USER_EMAIL:
context['social_email'] = self.kwargs['social_email']
context['social_fname'] = self.kwargs['social_fname']
context['social_lname'] = self.kwargs['social_lname']
context['social_uname'] = self.kwargs['social_uname']
# context['social_image'] = SOCIAL_USER_IMAGE
return context
# Passes view kwargs to form
def get_form_kwargs(self):
kwargs = super(RegisterView, self).get_form_kwargs()
kwargs.update(self.kwargs)
return kwargs
def form_valid(self, form):
form.save()
if not self.kwargs['social_email']:
return render(self.request, 'accounts/success.html', {
'title':"You've registered successfully",
'body':"You've successfully registered at antef! Please verify the link sent at " +
form.current_email
})
return render(self.request, 'accounts/success.html', {
'title':"You've registered successfully",
'body':"You've successfully registered with your " + self.kwargs['social_email'] + " account."})
Upvotes: 1
Views: 1846
Reputation: 1370
First, you don't need validation error for empty inputs, just add required = True
in your forms.py or in your model.
Second you are not returning anything after validation error, which making your form empty after refresh.
You can also check email and username separately, for better use,
def clean_email(self):
email = self.cleaned_data.get('email')
if your_condition:
raise forms.ValidationError()
return email
def clean_username(self):
username = self.cleaned_data.get('username')
if your_condition
raise forms.ValidationError
return username
Upvotes: 2