Django + ajax + 模态表单 bootstrap5.如何让它发挥作用?

Posted

技术标签:

【中文标题】Django + ajax + 模态表单 bootstrap5.如何让它发挥作用?【英文标题】:Django + ajax + modal form bootstrap5. How to make it work? 【发布时间】:2022-01-02 19:10:21 【问题描述】:

无论我多么努力都没有尝试固定 Ajax 请求。在成功的情况下,应该发生重定向,在失败的情况下 - 一个错误输出。已经尝试实施的所有方式,我不记得了。如果有人在这个例子中展示如何使用 Ajax,我将非常感激。以及在哪里正确注册?在基本模板中?因为如果你在模态模板中指定,在下载页面之前执行得太早了。

查看授权:

def login_view(request):
    """ Обработчик авторизаций, обращение происходит через ajax """

    # небольшая заглушка (Plug since one type of authorization is still disabled)
    if request.method == 'POST' and request.POST.get('type') == 'login':
        return JsonResponse('status': 'error', 'login_type': 'login', 'msg': 'На данный момент данный метод авторизаций не доступен!')

    if request.method == 'POST':
        if request.POST.get('type') == 'login':
            try:
                user: User = auth.authenticate(login=request.POST.get('login'), password=request.POST.get('password'))
            except Exception as error:
                return JsonResponse('status': 'error', 'login_type': 'login', 'msg': str(error))
            else:
                auth.login(request, user)
        elif request.POST.get('type') == 'token':
            try:
                user: User = auth.authenticate(token=request.POST.get('access_token'))
            except Exception as error:
                return JsonResponse('status': 'error', 'login_type': 'token', 'msg': str(error))
            else:
                auth.login(request, user)
        else:
            return JsonResponse('status': 'error', 'msg': 'Неизвестный тип авторизаций')
        return JsonResponse('status': 'ok')
    else:
        return JsonResponse('status': 'error', 'msg': 'Запрос должен быть POST')

授权模式:

% block content %
    <div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModalLabel" aria-hidden="true">
        <div class="modal-dialog" role="document">
            <div class="modal-content rounded-5 shadow">
                <div class="modal-header p-5 pb-4 border-bottom-0">
                    <h2 class="fw-bold mb-0" id="loginModalLabel">Авторизация</h2>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>

                <div class="modal-body p-5 pt-0">
                    <nav class="mb-3">
                        <div class="nav nav-tabs justify-content-center" id="nav-tab" role="tablist">
                            <button class="nav-link active" id="nav-login-tab" data-bs-toggle="tab"
                                    data-bs-target="#nav-login" type="button" role="tab" aria-controls="nav-login"
                                    aria-selected="true">По логину и паролю
                            </button>
                            <button class="nav-link" id="nav-token-tab" data-bs-toggle="tab"
                                    data-bs-target="#nav-token" type="button" role="tab" aria-controls="nav-token"
                                    aria-selected="false">По токену
                            </button>
                        </div>
                    </nav>
                    <div class="tab-content" id="nav-tabContent">
                        <div class="tab-pane fade show active" id="nav-login" role="tabpanel" aria-labelledby="nav-login-tab">
                            <form id="loginForm" method="post" action="% url 'login' %" disabled>
                                <div class="alert alert-danger" role="alert">
                                    На данный момент не работает, авторизация только по токену!
                                </div>
                                % csrf_token %
                                <input type="hidden" name="type" value="login">
                                <p>Небезопасный, но удобный способ авторизаций. Двухфакторная авторизация не
                                    поддерживается! Лучше используйте авторизацию по токену.</p>
                                <div class="form-floating mb-3">
                                    <input type="text" class="form-control rounded-4" id="login" name="login" placeholder="Логин от ВКонтакте" required>
                                    <label for="login">Логин от ВКонтакте</label>
                                </div>
                                <div class="form-floating mb-3">
                                    <input type="password" class="form-control rounded-4" id="password" name="password" placeholder="Пароль от ВКонтакте" required>
                                    <label for="password">Пароль от ВКонтакте</label>
                                </div>
                                <button class="w-100 mb-2 btn btn-lg rounded-4 btn-primary" id="logBtn" type="submit" disabled>Авторизация</button>
                                <small class="text-muted">Смена пароля отключит бота, нужно будет зайти на этот сайт, и авторизоваться ещё раз</small>
                            </form>
                        </div>
                        <div class="tab-pane fade" id="nav-token" role="tabpanel" aria-labelledby="nav-token-tab">
                            <p>Токен можно получить на <a href="https://vkhost.github.io" target="_blank">vkhost.github.io</a> через приложение Kate Mobile.</p>
                            <form id="tokenForm" method="post" action="% url 'login' %">
                                % csrf_token %
                                <input type="hidden" name="type" value="token">
                                <div class="form-floating mb-3">
                                    <input type="text" class="form-control rounded-4" id="access_token" name="access_token" placeholder="Токен от ВКонтакте" required>
                                    <label for="access_token">Токен от ВКонтакте</label>
                                </div>
                                <button class="w-100 mb-2 btn btn-lg rounded-4 btn-primary" type="submit">Авторизация</button>
                                <small class="text-muted">Смена пароля или выход со всех устройств отключат бота, нужно
                                    будет зайти на этот сайт, и авторизоваться ещё раз!</small>
                            </form>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
% endblock %

在基本模板连接bootstrap.min.css 和最后bootstrap.bundle.min.js

【问题讨论】:

【参考方案1】:

很可能,该解决方案不是很漂亮,但能够使用jquery-3.5.1.js 和jquery.form.js (v4.3.0) 实现。这是一个示例,代码在基本模板中。

let tokenLoginForm = $('#tokenForm');
tokenLoginForm.submit(function (e) 
    e.preventDefault();
    $.ajax(
        type: tokenLoginForm.attr('method'),
        url: tokenLoginForm.attr('action'),
        data: tokenLoginForm.serialize(),
        success: function (data) 
            if (data['status'] === 'error') 
                alert(data['msg'])
             else if (data['status'] === 'ok') 
                location.reload();
             else 
                alert('Авторизация вернула неизвестный статус!')
            
        ,
        error: function (data) 
            alert('Не удалось выполнить запрос! ' + data)
        ,
    );
);

【讨论】:

以上是关于Django + ajax + 模态表单 bootstrap5.如何让它发挥作用?的主要内容,如果未能解决你的问题,请参考以下文章

Django - Ajax 注册

Django:在模态中使用 Ajax 显示产品详细信息数据

实现 Django 3 模态表单的最佳方法是啥?

从 Django 模型中使用 Ajax 获取模态数据

在模态表单中使用 Spring Boot 和 thymeleaf 进行服务器端验证

用户更新表单后 Django 弹出消息(模态)