На сайте нужно релизовать формы регистрации и авторизации в модальных окнах, с возможностью аутентификации на всех страницах сайта + сделать валидацию форм на стороне клиента ( без перезагрузки страницы ). P.S. впервые реализовую аутентификацию таким образом
Так как формы с модальными окнами должны быть на всех страницах
login-view и
registration-view я добавил в
context_processors.py
context_processors.py:
def login_view(request): # Вьюшка для авторизации
if request.method == 'GET':
form_log = LoginForm(request.POST or None)
data = {
'form_log' : form_log,
}
return data
if request.method == 'POST':
if request.POST.get('submit') == 'Войти':
form_log = LoginForm(request.POST or None)
if form_log.is_valid():
username = form_log.cleaned_data['username']
password = form_log.cleaned_data['password']
user = authenticate(username=username, password=password)
if user:
profile = login(request, user)
return {}
data = {
'form_log' : form_log,
}
return data
return {}
def registration_view(request): # Вьюшка для регистрации
if request.method == 'GET':
form_reg = RegistrationForm(request.POST or None)
context = {
'form_reg' : form_reg,
}
return context
if request.method == 'POST':
if request.POST.get('submit') == 'Зарегистрироваться':
form_reg = RegistrationForm(request.POST or None)
if form_reg.is_valid():
new_user = form_reg.save(commit=False)
new_user.username = form_reg.cleaned_data['username']
new_user.email = form_reg.cleaned_data['email']
new_user.save()
new_user.set_password(form_reg.cleaned_data['password'])
new_user.save()
Profile.objects.create(
user=new_user,
)
user = authenticate(username=form_reg.cleaned_data['username'], password=form_reg.cleaned_data['password'])
login(request, user)
return {}
context = {
'form_reg' : form_reg,
}
return context
return {}
forms.py:
class LoginForm(forms.ModelForm): # Форма логина
password = forms.CharField(widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Логин'
self.fields['password'].label = 'Пароль'
def clean(self):
username = self.cleaned_data['username']
password = self.cleaned_data['password']
if not User.objects.filter(username=username).exists():
raise forms.ValidationError(f"Пользователь с логином {username} не найден")
user = User.objects.filter(username=username).first()
if user:
if not user.check_password(password):
raise forms.ValidationError("Неверный пароль")
return self.cleaned_data
class Meta:
model = User
fields = ['username', 'password']
class RegistrationForm(forms.ModelForm): # Форма регистрации
confirm_password = forms.CharField(widget=forms.PasswordInput)
password = forms.CharField(widget=forms.PasswordInput)
email = forms.EmailField(required=True)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Логин'
self.fields['password'].label = 'Пароль'
self.fields['confirm_password'].label = 'Подтвердите пароль'
self.fields['email'].label = 'Электронная пошта'
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise forms.ValidationError('Данный email уже зарегистрирован в системе')
return email
def clean_username(self):
username = self.cleaned_data['username']
if User.objects.filter(username=username).exists():
raise forms.ValidationError(f'Имя {username} занято')
return username
def clean(self):
password = self.cleaned_data['password']
confirm_password = self.cleaned_data['confirm_password']
if password != confirm_password:
raise forms.ValidationError('Пароли не совпадают')
return self.cleaned_data
class Meta:
model = User
fields = ['username', 'password', 'confirm_password', 'email']
base.html
<ul>
<li>
<a href="#" class="login popup-link" data-popup="popup-login"><i class="fas fa-sign-in-alt"></i>Авторизация</a>
</li>
<li>
<a href="#" class="registration popup-link" data-popup="popup-reg"><i class="fas fa-users"></i>Регистрация</a>
</li>
</ul>
<div id="popup-login" class="popup"> <!-- Модальное окно логина -->
<div class="popup_body">
<div class="popup_content">
<a href="" class="popup_close close-popup">X</a>
<div class="popup_title">Авторизация</div>
<div class="popup_text">
<form action="" method="POST">
<p class="error-list"></p>
{% csrf_token %}
<table>{{form_log.as_table}}</table>
<input type="submit" name="submit" value="Войти">
</form>
</div>
</div>
</div>
</div>
<div id="popup-reg" class="popup"> <!-- Модальное окно регистрации -->
<div class="popup_body">
<div class="popup_content">
<a href="" class="popup_close close-popup">X</a>
<div class="popup_title">Регистрация</div>
<div class="popup_text">
<form action="" method="POST">
{% csrf_token %}
<table>{{form_reg.as_table}}</table>
<input type="submit" name="submit" value="Зарегистрироваться">
</form>
</div>
</div>
</div>
</div>
Итого следующие проблемы:
1. Первое я сделал, формы авторизации и регистрации выводятся в модальных окнах на всех страницах - РЕШЕНО
2. Когда я отправляю POST запрос, пытяются отправиться сразу две формы - НЕ РЕШЕНО
3. Валидация - НЕ РЕШЕНО
Вся сложность в реализации валидации в том что
context_processors.py возвращает только словари а мне нужен JsonResponse()
P.S. Я первый раз реализовую нечто подобное, поэтому не особо разобрался как это лучше всего реализовать