I tried to implement django allauth app with SignupForm override, my code almost works when entering data into the signup form and saves users, but after save, I redirected to a new page that showed me 'NoneType' object has no attribute 'session'
AttributeError.
How can I fix it?
from django.urls import path
from .views import login, logout, AllauthSignUpView
app_name = 'register'
urlpatterns = [
path('login/', login, name='login'),
path('signup/', AllauthSignUpView.as_view(), name='signup'),
path('logout/', logout, name='logout'),
]
override SignupView As follows as:
from django.shortcuts import render, HttpResponseRedirect
from .form import AllauthLoginForm, AllauthSignUpForm
from allauth.account.views import SignupView
from django.urls import reverse_lazy
class AllauthSignUpView(SignupView):
template_name = 'register/signup.html'
form_class = AllauthSignUpForm
success_url = reverse_lazy('core:home') #Redirect to home.html
def form_valid(self, form):
# This method is called when valid form data has been POSTed.
if form.is_valid():
form.save()
form.clean()
return HttpResponseRedirect('core:home') #Redirect to home.html
# It should return an HttpResponse.
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super(AllauthSignUpView, self).get_context_data(**kwargs)
signUpForm = AllauthSignUpForm(self.request.POST or None)
context['form'] = signUpForm
return context
override SignupForm As follows as:
from allauth.account.forms import LoginForm, SignupForm
from django import forms
class AllauthSignUpForm(SignupForm):
def __init__(self, *args, **kwargs):
super(AllauthSignUpForm, self).__init__(*args, **kwargs)
self.fields['username'] = forms.CharField(
label='',
widget=forms.TextInput(
attrs={
'class': 'signup_name_inp text-right mb-4 border-top-0 border-right-0 border-left-0',
'placeholder': 'نام کاربری',
'dir': 'rtl',
}
),
)
self.fields['email'] = forms.EmailField(
label='',
widget=forms.EmailInput(
attrs={
'class': 'signup_mail_inp text-right mb-4 border-top-0 border-right-0 border-left-0',
'placeholder': 'ایمیل (اختیاری)',
'dir': 'rtl',
}
)
)
self.fields['password1'] = forms.CharField(
label='',
widget=forms.PasswordInput(
attrs={
'class': 'signup_pass_inp1 text-right mb-4 border-top-0 border-right-0 border-left-0',
'placeholder': 'کلمه عبور',
'dir': 'rtl',
}
)
)
self.fields['password2'] = forms.CharField(
label='',
widget=forms.PasswordInput(
attrs={
'class': 'signup_pass_inp2 text-right mb-4 border-top-0 border-right-0 border-left-0',
'placeholder': 'تکرار کلمه عبور',
'dir': 'rtl'
}
)
)
def save(self, request=None):
# Ensure you call the parent class's save.
# .save() returns a User object.
user = super(AllauthSignUpForm, self).save(request)
# Add your own processing here.
print(user.username)
# You must return the original result.
return user
<form dir='rtl' class="text-right border-0 p-5 bg-transparent" id="signup_form" method="post" action="{% url 'register:signup' %}" >
{% csrf_token %}
{{ form|crispy }}
<div class="row">
<div class="col-12">
<button class="btn btn-outline-info btn-block z-depth-0 my-4 waves-effect rounded-pill" type="submit">{% trans "ثبت نام" %} »</button>
</div>
<div class="col-12">
<p class="float-right mt-3" >آیا اکانت ساخته اید؟ <a class="font-weight-bold" href="{% url 'register:login' %}" style="color: #858585 !important;">وارد شوید</a>.</p>
</div>
</div>
</form>
ACCOUNTS_FORMS = {
'login': 'registerations.form.AllauthLoginForm',
'signup': 'registerations.form.AllauthSignUpForm',
'add_email': 'allauth.account.forms.AddEmailForm',
'change_password': 'allauth.account.forms.ChangePasswordForm',
'set_password': 'allauth.account.forms.SetPasswordForm',
'reset_password': 'allauth.account.forms.ResetPasswordForm',
'reset_password_from_key': 'allauth.account.forms.ResetPasswordKeyForm',
'disconnect': 'allauth.socialaccount.forms.DisconnectForm',
}
There are some useful link below: help-1
There look to be a few potential issues with your code but the main one that's likely causing your stated issue is that you're not passing the request
object to your form.save()
call in your views.py
file.
It should look something more like this:
def form_valid(self, form):
# Don't do this. form_valid() only gets called on a valid form anyway
# if form.is_valid():
form.save(self.request)
# No need to call form.clean() again, especially after already saving the form
# form.clean()
return HttpResponseRedirect('core:home') #Redirect to home.html
So, in summary, you don't really seem to be doing anything "custom" in your custom form_valid()
function, so you're probably better off completely removing it and just using the one defined in the parent class. You've already specified your success_url
so you can let allauth's form_valid()
do the work for you.