Ошибка AttributeError at /auth/login/ 'NoneType' object has no attribute 'has_header'
Использую python/django. Для мультистраничной регистрации использую библиотеку https://github.com/ImaginaryLandscape/django-multipage-form. При регистрации пользователя через эту форму - пароль сохраняется без хеша, поэтому я воспользовался сигналом @pre_save в модели пользователя и добавил туда использование функции set_password. При регистрации обычного пользователя и дальнейшем логине функция check_password возвращает false, хотя при регистрации админа и его логине - функция возвращает true.
authapp models:
class Interests(models.Model):
interest_category_title = models.CharField(
max_length=64,
blank=False,
verbose_name='категория интересов'
)
def __str__(self):
return self.interest_category_title
class Countries(models.Model):
country_name = models.CharField(
verbose_name='название страны',
max_length=64,
unique=True,
blank=False
)
def __str__(self):
return self.country_name
class Cities(models.Model):
country = models.ForeignKey(
Countries,
on_delete=models.CASCADE
)
city_name = models.CharField(
max_length=64,
verbose_name='название города',
unique=True,
blank=False
)
def __str__(self):
return self.city_name
class Genders(models.Model):
gender = models.CharField(
max_length=10,
unique=True,
blank=False,
verbose_name='пол'
)
def __str__(self):
return self.gender
class UserProfile(MultipageModel, AbstractUser):
avatar = models.ImageField(
upload_to='users_avatars',
blank=True
)
gender = models.ForeignKey(
Genders,
blank=True,
on_delete=models.SET_NULL,
null=True
)
country = models.ForeignKey(
Countries,
on_delete=models.SET_NULL,
null=True
)
city = models.ForeignKey(
Cities,
on_delete=models.SET_NULL,
null=True
)
phone_number = PhoneNumberField()
interests = models.ManyToManyField(
Interests,
blank=True
)
objects = UserManager()
REQUIRED_FIELDS = ['phone_number']
@receiver(pre_save, sender=UserProfile)
def hash_user_passw_and_save(sender, instance, **kwargs):
instance.set_password(instance.password)
class UserProfileMoreInfo(models.Model):
user = models.OneToOneField(
UserProfile,
unique=True,
null=True,
on_delete=models.CASCADE
)
bio = models.CharField(
verbose_name='биография',
max_length=5000,
blank=True
)
verification_date = models.DateField(
verbose_name='дата подтверждения аккаунта',
null=True
)
authapp managers:
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, username=None, phone_number=None,
password=None, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
if not username:
if not phone_number:
raise ValueError('The given email/phone must be set')
if phone_number:
if not username:
username = phone_number
user = self.model(
username=username,
phone_number=phone_number,
**extra_fields
)
if extra_fields.get('is_superuser'):
user = self.model(
username=username,
phone_number=phone_number,
**extra_fields
)
user.set_password(str(password))
user.save(using=self._db)
return user
def create_user(self, username, phone_number, password=None, **extra_fields):
extra_fields.setdefault('is_superuser', False)
return self._create_user(username=username, phone_number=phone_number, password=password, **extra_fields)
def create_superuser(self, username, password, phone_number, **extra_fields):
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(
username=username,
password=password,
phone_number=phone_number,
**extra_fields
)
authapp backends:
User = get_user_model()
class PhoneUsernameAuthBackend(object):
def authenticate(self, request, username=None, password=None):
try:
user = User.objects.get(
Q(username=username) | Q(phone_number=username)
)
except User.DoesNotExists:
return None
if user and check_password(password, user.password):
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExists:
return None
authapp views:
class UserRegisterView(MultipageFormView):
template_name = 'authapp/register.html'
form_class = UserRegisterForm
success_url = reverse_lazy("authapp:login")
class UserLoginView(LoginView):
form_class = UserLoginForm
template_name = 'authapp/login.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['fields'] = '__all__'
return dict(list(context.items()))
def post(self, request, *args, **kwargs):
form = self.get_form()
if form.is_valid():
self.form_valid(form)
return HttpResponseRedirect(reverse('index'))
authapp_forms:
class UserLoginForm(AuthenticationForm):
class Meta:
model = UserProfile
fields = ('username', 'password')
def __init__(self, *args, **kwargs):
super(UserLoginForm, self).__init__(*args, **kwargs)
for field_name, filed in self.fields.items():
if field_name == 'username':
filed.label = 'Username or phone number'
class UserRegisterForm(MultipageForm, ModelForm):
model = UserProfile
starting_form = 'Stage1Form'
class Stage1Form(ChildForm):
model = UserProfile
template_name = 'authapp/register.html'
display_name = 'Personal info'
required_fields = '__all__'
next_form_class = 'Stage2Form'
class Meta:
fields = ['username', 'phone_number', 'city', 'password']
class Stage2Form(ChildForm):
template_name = 'authapp/register.html'
display_name = 'GenderChoice'
required_fields = '__all__'
next_form_class = 'Stage3Form'
class Meta:
fields = ['gender']
def get_next_form_class(self):
return "Stage3Form"
class Stage3Form(ChildForm):
template_name = 'authapp/register.html'
display_name = 'Interests'
required_fields = '__all__'
class Meta:
fields = ['interests']