"AttributeError: 'NoneType' object has no attribute 'session' " when override SignupForm in django allauth app

"AttributeError: 'NoneType' object has no attribute 'session' " when override SignupForm in django allauth app

我尝试用 SignupForm override 实现 django allauth 应用程序,我的代码几乎可以工作在注册表单中输入数据并保存用户时,但保存后,我重定向到一个显示 'NoneType' object has no attribute 'session' AttributeError 的新页面。 我该如何解决?

urls.py

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'),
]

views.py

重写 SignupView 如下:

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

form.py

重写 SignupForm 如下:

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

signup.html

          <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 "ثبت نام" %} &raquo;</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>

settings.py

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',
}

下面有一些有用的 link: help-1

您的代码似乎存在一些潜在问题,但可能导致您所述问题的主要原因是您没有将 request 对象传递给您的 form.save() 调用views.py 文件。

它应该看起来更像这样:

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

所以,总而言之,您似乎并没有在自定义 form_valid() 函数中做任何事情 "custom",所以您最好完全删除它并只使用一个在父 class 中定义。您已经指定了 success_url,因此您可以让 allauth 的 form_valid() 为您完成这项工作。