G
G
GrayDead2021-08-31 18:52:17
Django
GrayDead, 2021-08-31 18:52:17

Django how to implement ( Login&Registration Forms) in Modal windows on all pages + client-side validation?

The site needs to release registration and authorization forms in modal windows, with the ability to authenticate on all pages of the site + validate forms on the client side (without reloading the page). PS for the first time implementing authentication in this way.

Since forms with modal windows should be on all login-view and registration-view pages, I added context_processors.py to

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>


In total, the following problems:
1. The first I did, the authorization and registration forms are displayed in modal windows on all pages - RESOLVED
2. When I send a POST request, two forms are trying to go at once - NOT RESOLVED
3. Validation - NOT RESOLVED

All the complexity in the implementation of validation in that context_processors.py returns only dictionaries and I need JsonResponse()

PS I'm implementing something like this for the first time, so I didn't really figure out how best to implement it

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question