@GrayDead

Django как реализовать ( Login&Registration Forms) в Модальных окнах на всех страницах + валидация на стороне клиента?

На сайте нужно релизовать формы регистрации и авторизации в модальных окнах, с возможностью аутентификации на всех страницах сайта + сделать валидацию форм на стороне клиента ( без перезагрузки страницы ). 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. Я первый раз реализовую нечто подобное, поэтому не особо разобрался как это лучше всего реализовать
  • Вопрос задан
  • 982 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы