Django регистрация и авторизация через функции
Не могу найти решение задачи.
На сайте нужна регистрация пользователя в дополнительными полями. И авторизация через email. Поля я добавил через дополнительную модель:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.IntegerField('Телефон', null=True, blank=True)
country = models.CharField('Страна', max_length=100, null=True, blank=True)
city = models.CharField('Город', max_length=100, null=True, blank=True)
adress = models.CharField('Улица и дом', max_length=300, null=True, blank=True)
zip_code = models.IntegerField('Почтовый индекс', null=True, blank=True)
birth_day = models.DateField('День рождения', null=True, blank=True)
avatar = models.ImageField('Аватар', upload_to='avatar', null=True, blank=True)
agreement = models.BooleanField('Согласие на обработку', default=True)
comment = models.TextField('Комментарии', max_length=3000, null=True, blank=True)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
def admin_display(self):
return self.user.last_name + ' ' + self.user.first_name
Далее сделал 2 формы для отображения в шаблоне:
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
exclude = ('comment', 'register_date', 'avatar', 'password', )
widgets = {
'phone': forms.NumberInput(attrs={'placeholder': '9XXXXXXXXX', 'class': 'form-control', 'id': 'phone'}),
'country': forms.TextInput(attrs={'placeholder': 'Россия', 'class': 'form-control', 'id': 'country'}),
'city': forms.TextInput(attrs={'placeholder': 'Москва', 'class': 'form-control', 'id': 'city'}),
'adress': forms.TextInput(attrs={'placeholder': 'Ленина 25', 'class': 'form-control', 'id': 'adress'}),
'zip_code': forms.TextInput(attrs={'placeholder': '101000', 'class': 'form-control', 'id': 'zip_code'}),
'agreement': forms.CheckboxInput(attrs={'class': 'form-check-input', 'id': 'flexSwitchCheckChecked'}),
'birth_day': DateInput(attrs={'class': 'form-control', 'id': 'birth_day'}),
}
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ('first_name', 'last_name', 'email', 'password',)
widgets = {
'first_name': forms.TextInput(attrs={'placeholder': 'Иван', 'class': 'form-control', 'id': 'first_name'}),
'last_name': forms.TextInput(attrs={'placeholder': 'Петров', 'class': 'form-control', 'id': 'last_name'}),
'email': forms.EmailInput(attrs={'placeholder': 'ivan_petrov@email.ru', 'class': 'form-control', 'id': 'email'}),
'password': forms.PasswordInput(attrs={'placeholder': 'Пароль', 'class': 'form-control', 'id': 'password'}),
}
Я не вывожу поле username. Вместо этого добавляю туда email. Пользователь создаётся. Только пароль почему-то не зашифрован. И залогиниться этот пользователь не может. Получаю ошибку соответствия логина\пароля. И не могу найти пример функции логина. Прошу помочь с этим.
Перед сохранением пользователя, сделайте user.set_password(<пароль>)
Далее, по ошибкам:
form = UserForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.username = request.POST['email']
Уже неправильно, instance.username = request.POST['email']
. В форму поступает некорректное имя (поле username
пусто). Поэтому и возникает ошибка. Как и остальные поля.
Можете в clean
формы сделать cleaded_data['username'] = cleacned_data['email']
UPD:
Если кратко, то Вам нужно создать модель от django.contrib.auth.models.AbstractUser
по аналогии с django.contrib.auth.models.User
, убрав все лишнее, и указать полученную модель как модель для пользователей в setttings.py
(AUTH_USER_MODEL
).
В вашем случае, новая модель будет выглядеть так
class MyUser(AbstractUser):
"""
An abstract base class implementing a fully featured User model with
admin-compliant permissions.
Username and password are required. Other fields are optional.
"""
username = None
EMAIL_FIELD = 'email'
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['email']
В этом случае, для указания связи на пользователя в ForeignKey
и ManyToMany
и OneToOneField
лучше использовать get_user_model()
, а и вообще лучше использовать эту функцию, а не указания конкретного класса.
Больше информации найдете по запросу custom user model django
в поисковике, ниже ссылка с примером