Обработка нескольких входных значений для одной HTML-формы в Django - PullRequest
0 голосов
/ 29 октября 2018

У меня есть HTML-форма с 3 кнопками ввода и шагов.

  • 1 ST Шаг пользователь должен ввести имя и нажать кнопку 1
  • 2 и Шаговый пользователь должен ввести фамилию и нажать кнопку 2
  • 3 rd Шаг пользователь должен поставить электронную почту и нажать кнопку финала 3

Каждый раз, когда пользователь нажимает любую кнопку, затем переходят к следующему шагу html.

Я хочу обрабатывать вводы в моем views.py шаг за шагом в любое время, когда пользователь нажимает любую кнопку, и не все вместе в окончательном представлении .

Я попробовал этот код в views.py, чтобы получить входные данные в бэкэнде django, но я ничего не получил в views.py (если я изменил тип кнопки с button на submit, тогда я получу страницу обновления ореха результатов и Я не могу перейти к шагу 2)

views.py

if request.method == 'POST' and 'first_step' in request.POST:
    print '1'
    firstname= request.POST.get('firstname')
if request.method == 'POST' and 'second_step' in request.POST:
    print '2'
    lastname= request.POST.get('lastname')
if request.method == 'POST' and 'final_step' in request.POST:
    print '3'
    email= request.POST.get('email')

Вот мой HTML-код:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">

    <title>Form wizard with circular tabs</title>

    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <section>
        <div class="wizard">
            <div class="wizard-inner">
                <div class="connecting-line"></div>
                <ul class="nav nav-tabs" role="tablist">

                    <li role="presentation" class="active">
                        <a href="#step1" data-toggle="tab" aria-controls="step1" role="tab" title="Step 1">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-folder-open"></i>
                            </span>
                        </a>
                    </li>

                    <li role="presentation" class="disabled">
                        <a href="#step2" data-toggle="tab" aria-controls="step2" role="tab" title="Step 2">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-pencil"></i>
                            </span>
                        </a>
                    </li>
                    <li role="presentation" class="disabled">
                        <a href="#step3" data-toggle="tab" aria-controls="step3" role="tab" title="Step 3">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-picture"></i>
                            </span>
                        </a>
                    </li>

                    <li role="presentation" class="disabled">
                        <a href="#complete" data-toggle="tab" aria-controls="complete" role="tab" title="Complete">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-ok"></i>
                            </span>
                        </a>
                    </li>
                </ul>
            </div>

            <form role="form">
                <div class="tab-content">
                    <div class="tab-pane active" role="tabpanel" id="step1">
                        <div class="step1">
                            <div class="row">
                            <div class="col-md-6">
                                <label for="exampleInputEmail1">First Name</label>
                                <input type="email" name="firstname" class="form-control" id="exampleInputEmail1" placeholder="First Name">
                            </div>

                        </div>

                        </div>
                        <ul class="list-inline pull-right">
                            <li><button type="button" name="first_step" class="btn btn-primary next-step">Save and continue</button></li>
                        </ul>
                    </div>
                    <div class="tab-pane" role="tabpanel" id="step2">
                        <div class="step2">

                            <div class="step-22">
                                                <label for="exampleInputEmail1">Last Name</label>
                                <input type="email" name="lastname" class="form-control" id="exampleInputEmail1" placeholder="Last Name">
                            </div>
                        </div>
                        <ul class="list-inline pull-right">
                            <li><button type="button" class="btn btn-default prev-step">Previous</button></li>
                            <li><button type="button" name="second_step" class="btn btn-primary next-step">Save and continue</button></li>
                        </ul>
                    </div>
                    <div class="tab-pane" role="tabpanel" id="step3">
                        <div class="step33">


                                                    <label for="exampleInputEmail1">email</label>
                                <input type="email" name="email" class="form-control" id="exampleInputEmail1" placeholder="Last Name">



                        </div>
                        <ul class="list-inline pull-right">
                            <li><button type="button" class="btn btn-default prev-step">Previous</button></li>
                            <li><button type="button" name="final_step" class="btn btn-primary btn-info-full next-step">Save and continue</button></li>
                        </ul>
                    </div>
                    <div class="tab-pane" role="tabpanel" id="complete">
                        <div class="step44">
                            <h5>Completed</h5>


                        </div>
                    </div>
                    <div class="clearfix"></div>
                </div>
            </form>
        </div>
    </section>
   </div>
</div>
<script type="text/javascript">
$(document).ready(function () {
    //Initialize tooltips
    $('.nav-tabs > li a[title]').tooltip();

    //Wizard
    $('a[data-toggle="tab"]').on('show.bs.tab', function (e) {

        var $target = $(e.target);

        if ($target.parent().hasClass('disabled')) {
            return false;
        }
    });

    $(".next-step").click(function (e) {

        var $active = $('.wizard .nav-tabs li.active');
        $active.next().removeClass('disabled');
        nextTab($active);

    });
    $(".prev-step").click(function (e) {

        var $active = $('.wizard .nav-tabs li.active');
        prevTab($active);

    });
});

function nextTab(elem) {
    $(elem).next().find('a[data-toggle="tab"]').click();
}
function prevTab(elem) {
    $(elem).prev().find('a[data-toggle="tab"]').click();
}


//according menu

$(document).ready(function()
{
    //Add Inactive Class To All Accordion Headers
    $('.accordion-header').toggleClass('inactive-header');

    //Set The Accordion Content Width
    var contentwidth = $('.accordion-header').width();
    $('.accordion-content').css({});

    //Open The First Accordion Section When Page Loads
    $('.accordion-header').first().toggleClass('active-header').toggleClass('inactive-header');
    $('.accordion-content').first().slideDown().toggleClass('open-content');

    // The Accordion Effect
    $('.accordion-header').click(function () {
        if($(this).is('.inactive-header')) {
            $('.active-header').toggleClass('active-header').toggleClass('inactive-header').next().slideToggle().toggleClass('open-content');
            $(this).toggleClass('active-header').toggleClass('inactive-header');
            $(this).next().slideToggle().toggleClass('open-content');
        }

        else {
            $(this).toggleClass('active-header').toggleClass('inactive-header');
            $(this).next().slideToggle().toggleClass('open-content');
        }
    });

    return false;
});
</script>
</body>
</html>

Ответы [ 4 ]

0 голосов
/ 08 ноября 2018

Мне не совсем понятно в вопросе, что такое желаемое поведение. Как кто-то указал, это может быть вопрос дизайна.

При «обработке входных данных в моем views.py шаг за шагом» мне кажется, что данные желательно размещать для каждого шага и обрабатывать бэкэндом? (Ajax или нет)

Если для каждого шага без ajax желательно иметь цикл пост-ответа, предыдущие шаги должны быть частью возвращенного контекста / шаблона, и возможно «обработать» шаг в бэкэнде.

Существует довольно мощный инструмент для ситуаций такого типа, FormWizard в django, и это может дать вам вдохновение для вашего конкретного решения?

0 голосов
/ 02 ноября 2018

Возможным и непроверенным решением было бы сделать атрибуты вашей модели обнуляемыми / пустыми. Показанный ниже сохраните связанный атрибут объекта записи. Следовательно, вы можете устанавливать атрибуты один за другим с каждым условием if, не получая никакой пустой или пустой ошибки. Также, если вы не хотите обновлять страницу при каждом нажатии, вы можете использовать AJAX.

При каждом щелчке устанавливать variable=buttonId и if условия в view, например if variable == 0, а также каждый раз, когда передается значение номера кнопки в качестве аргумента для представления, если такие условия, как view(request, buttonId), сохраняют связанный атрибут объекта , а затем перенаправить на следующий HTML` с тем же видом.

0 голосов
/ 06 ноября 2018

Я думаю, что вижу, куда вы пытаетесь пойти, но, как уже говорили другие пользователи, это не вопрос Django, а вопрос дизайна.

По сути, вы ВСЕГДА собираетесь попасть в кирпичную стену при попытке отправить информацию на сервер через отправку. Вам НУЖНО использовать AJAX, если вы хотите эту функциональность.

Кроме того, у вас есть два реальных варианта:

  1. Создание решения для состояния в javascript, который будет отслеживать информацию о форме через шаги 1 и 2, а затем отправлять данные формы по завершении шага 3.
  2. Создайте асинхронное решение с использованием AJAX для публикации частичных данных на вашем сервере (для этого потребуется обновить код представления, чтобы принимать частичные данные вместо всей модели Django).

Здесь вы можете узнать, как использовать jQuery для выполнения предложения № 2.

0 голосов
/ 02 ноября 2018

Несколько часов назад я написал ответ на эту проблему, затем удалил его, потому что мне пришлось осознать, что я только частично дал решение этой проблемы, поскольку эта проблема немного сложнее, чем кажется на первый взгляд.

Как пишет ОП: если вы используете кнопку type = "submit" , ввод будет отправлен, но в то же время страница обновится и с этой формой это не цель. И если вы используете вход type = "button" , то входные данные не попадут на сервер (только если вы соберете отправленные данные в объект javascript, а затем запустите AJAX-вызов и отправите его сервер с этим AJAX-запросом).

По сути, это также не вопрос Django, а скорее вопрос о вызовах javascript / AJAX. А также вызывает немного вопросов безопасности для решения. Так как с представлениями вам также нужно как-то отправить токен CSRF на сервер. Таким образом, это может быть решено, это займет некоторое время.

Хороший источник на эту тему здесь: https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html (однако, эта статья в некоторой части бесполезна в данном конкретном случае)

ТАК, КАК ЭТО РАБОТАЕТ

Давным-давно Я не работал с Django и Python (в настоящее время больше похож на PHP и Joomla), но я просто установил Django 2.1.3 на Python 3.7, чтобы убедиться, что это работает (следующее должно работать и в более старых версиях, с небольшими изменениями, если это необходимо)

Я создал приложение под названием «myuserform» и сначала создал Model в models.py

models.py

from django.db import models
from django.utils import timezone

class NewUser(models.Model):
    first_name = models.CharField(max_length=150)
    last_name = models.CharField(max_length=150)
    email = models.EmailField(max_length=254)
    creation_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.first_name, self.last_name

Затем я создал форму в forms.py (важно: сначала создайте Model, затем ModelForm в Django, если вы создаете Forms в Django - именно так вы должны правильно выполнять эти задания)

forms.py

from django import forms
from django.forms import ModelForm
from myuserform.models import NewUser

# Create the form class.
class NewUserForm(ModelForm):
    class Meta:
        model = NewUser
        fields = ['first_name', 'last_name', 'email']

Поскольку HTML-форма уже была предоставлена ​​OP здесь выше, тогда я просто создал два шаблона из них в папке templates моего приложения 'myuserform'. A base.html и regform.html (меня сейчас не беспокоило создание хороших шаблонов)

  1. Мне пришлось переименовать поля ввода (имя) формы HTML, чтобы они были совместимы с моей формой и моделью Django (имена полей ввода должны совпадать с именами полей формы Django и полей модели).

Я также немного очистил поля ввода, чтобы они хорошо работали с кодами javascript, добавив атрибут onclick к кнопкам, который запускает различные пользовательские функции javascript (это может быть очень упрощено при выборе элементов jQuery конечно). последняя кнопка будет отправлять форму через AJAX. (вам не нужно отдельно отправлять или собирать входные данные в Django, по моему мнению, это избыточно - поскольку вы хотите, чтобы делать с входными данными по имени, например "Джо" ? Ничего). Вы также можете предварительно проверять входные данные шаг за шагом с помощью javascript - я тоже добавил эти функции, однако эти функции предварительной проверки могли бы быть расширены. Теперь он только проверяет, является ли поле пустым или нет, а поле электронной почты является допустимым вводом формата электронной почты или нет, и не позволяет вам продолжить, если это не так).

  1. Теперь это важная часть. Разумеется, шаблоны должны создаваться с помощью тегов стиля Django, а пользовательские файлы javascript должны импортироваться из созданной папки js . Я просто копирую здесь шаблоны HTML из Django. Одна важная вещь заключается в том, что я поместил защищенный токен csrf в данную HTML-форму и написал несколько добавленных javascript / jquery-кодов в части сценария HTML.И вторая наиболее важная часть - это написанная мной функция javascript, которая называется function sendNuData () , которая отправляет входные данные Form в представление Django с использованием AJAX-вызов.

in templates / base.html

<!DOCTYPE html>
<html lang="en">
<head>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>

    <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

    <title>{% block title %}My amazing site homepage{% endblock %}</title>

</head>

<body>    

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

in templates / regform.html

{% extends "base.html" %}

{% block title %}My amazing Registration Form{% endblock %}

{% block content %}

<h1>{{title}}</h1><br>

<div class="container">
    <div class="row">
      <div class="col-md-6">
        <section>
        <div class="wizard">
            <div class="wizard-inner">
                <div class="connecting-line"></div>
                <ul class="nav nav-tabs" role="tablist">

                    <li role="presentation" class="active">
                        <a href="#step1" data-toggle="tab" aria-controls="step1" role="tab" title="Step 1">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-folder-open"></i>
                            </span>
                        </a>
                    </li>

                    <li role="presentation" class="disabled">
                        <a href="#step2" data-toggle="tab" aria-controls="step2" role="tab" title="Step 2">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-pencil"></i>
                            </span>
                        </a>
                    </li>
                    <li role="presentation" class="disabled">
                        <a href="#step3" data-toggle="tab" aria-controls="step3" role="tab" title="Step 3">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-picture"></i>
                            </span>
                        </a>
                    </li>

                    <li role="presentation" class="disabled">
                        <a href="#complete" data-toggle="tab" aria-controls="complete" role="tab" title="Complete">
                            <span class="round-tab">
                                <i class="glyphicon glyphicon-ok"></i>
                            </span>
                        </a>
                    </li>
                </ul>
            </div>

            <form role="form" id="login-form" action="#" method="post">
                {% csrf_token %}
                <div class="tab-content">
                    <div class="tab-pane active" role="tabpanel" id="step1">
                        <div class="step1">
                            <div class="row">
                            <div class="col-md-6">
                                <label for="exampleInputEmail1">First Name</label>
                                <input type="text" name="first_name" class="form-control" id="exampleInputEmail1" placeholder="First Name">
                            </div>
                            </div>
                        </div>
                        <ul class="list-inline pull-right">
                            <li><button type="button" name="first_step" class="btn btn-primary" onclick="getFirstNameMove()">Save and continue</button></li>
                        </ul>
                    </div>
                    <div class="tab-pane" role="tabpanel" id="step2">
                        <div class="step2">

                            <div class="step-22">
                                                <label for="exampleInputEmail1">Last Name</label>
                                <input type="text" name="last_name" class="form-control" id="exampleInputEmail2" placeholder="Last Name">
                            </div>
                        </div>
                        <ul class="list-inline pull-right">
                            <li><button type="button" class="btn btn-default prev-step">Previous</button></li>
                            <li><button type="button" name="second_step" class="btn btn-primary" onclick="getLastNameMove()">Save and continue</button></li>
                        </ul>
                    </div>
                    <div class="tab-pane" role="tabpanel" id="step3">
                        <div class="step3">
                          <div class="step-33">


                                                    <label for="exampleInputEmail1">email</label>
                                <input type="email" name="email" class="form-control" id="exampleInputEmail3" placeholder="email address">



                        </div>
                        <ul class="list-inline pull-right">
                            <li><button type="button" class="btn btn-default prev-step">Previous</button></li>
                            <li><button type="button" name="final_step" id="final_step" class="btn btn-primary btn-info-full" onclick="getEmailMove()">Save and continue</button></li>
                        </ul>
                        </div>
                    </div>
                    <div class="tab-pane" role="tabpanel" id="complete">
                        <div class="step44">
                            <h5>Completed</h5>


                        </div>
                    </div>
                    <div class="clearfix"></div>
                </div>
            </form>
        </div>
    </section>
   </div>
  </div>
</div>

<script type="text/javascript">

$ = jQuery.noConflict();

$(document).ready(function () {
    //Initialize tooltips
    $('.nav-tabs > li a[title]').tooltip();

    //Wizard
    $('a[data-toggle="tab"]').on('show.bs.tab', function (e) {

        var $target = $(e.target);

        if ($target.parent().hasClass('disabled')) {
            return false;
        }
    });

    $(".next-step").click(function (e) {

        var $active = $('.wizard .nav-tabs li.active');
        $active.next().removeClass('disabled');
        nextTab($active);

    });
    $(".prev-step").click(function (e) {

        var $active = $('.wizard .nav-tabs li.active');
        prevTab($active);

    });
});

function getFirstNameMove() {
    if (checkFirstName()) {
        moveNextTab();
    }
}

function getLastNameMove() {
    if (checkLastName()) {
        moveNextTab();
    }
}

function getEmailMove() {
    if (checkEmail()) {
        moveNextTab();
        sendNuData();
    }
}

function checkFirstName() {
    form = document.getElementById('login-form');

    if (form.first_name.value == '') {
        alert('Cannot leave First name field blank.');
        form.first_name.focus();
        return false;
    }
    return true;
}

function checkLastName() {
    form = document.getElementById('login-form');

    if (form.last_name.value == '') {
        alert('Cannot leave Last name field blank.');
        form.last_name.focus();
        return false;
    }
    return true;
}

function checkEmail() {
    form = document.getElementById('login-form');
    let newEmail = form.email.value;

    if (newEmail == '') {
        alert('Cannot leave email field blank.');
        form.email.focus();
        return false;
    }

    if (emailValidate(newEmail)) {
        return true;
    } else {
        alert('Please provide a valid email address.');
        form.email.focus();
        return false;
    }

}

function emailValidate(sEmail) {
    let filter = /^([\w-.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$/;
    return filter.test(sEmail);
}

function moveNextTab() {
    var $active = $('.wizard .nav-tabs li.active');
        $active.next().removeClass('disabled');
            nextTab($active);
}

function nextTab(elem) {
    $(elem).next().find('a[data-toggle="tab"]').click();
}
function prevTab(elem) {
    $(elem).prev().find('a[data-toggle="tab"]').click();
}

function sendNuData(){

    $.ajaxSetup({
        beforeSend: function(xhr, settings) {
            function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie != '') {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = jQuery.trim(cookies[i]);
                        // Does this cookie string begin with the name we want?
                        if (cookie.substring(0, name.length + 1) == (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                            break;
                        }
                    }
                }
                return cookieValue;
            }
            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                // Only send the token to relative URLs i.e. locally.
                xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
            }
        }
    });

    $.ajax({
        url: '/get_allform_data/',
        method: 'post',
        data: $('form').serialize(),
        contentType: false,            
        success: function (data) {
            alert('Form Submitted');
            // console.log(data);
        },
        error: function(data) {
            alert('Form submission failed');
            // console.log(data);
        }
    });
}

//according menu

$(document).ready(function()
{
    //Add Inactive Class To All Accordion Headers
    $('.accordion-header').toggleClass('inactive-header');

    //Set The Accordion Content Width
    var contentwidth = $('.accordion-header').width();
    $('.accordion-content').css({});

    //Open The First Accordion Section When Page Loads
    $('.accordion-header').first().toggleClass('active-header').toggleClass('inactive-header');
    $('.accordion-content').first().slideDown().toggleClass('open-content');

    // The Accordion Effect
    $('.accordion-header').click(function () {
        if($(this).is('.inactive-header')) {
            $('.active-header').toggleClass('active-header').toggleClass('inactive-header').next().slideToggle().toggleClass('open-content');
            $(this).toggleClass('active-header').toggleClass('inactive-header');
            $(this).next().slideToggle().toggleClass('open-content');
        }

        else {
            $(this).toggleClass('active-header').toggleClass('inactive-header');
            $(this).next().slideToggle().toggleClass('open-content');
        }
    });

    return false;
});
</script>

{% endblock %}

Тогда одна из самых сложных частей, , которая является вопросом , как обрабатывать / или сохранять данные вызовов AJAX , отправленные Django из Отправка формы ( поэтому форма не отправляется с помощью обычной кнопки отправки (с обычным HTTP-запросом), что было бы очень известным, относительно простым делом и задачей, которую нужно обработать).

Будет 2 вещи , с которыми вы столкнетесь при отправке и отправке входных данных в форме HTML через вызов AJAX в Django:

1. Данные запроса будут в объекте запроса WSGI , в противном случае неизменяемый формат Querydict , который не может быть обработан простым вызовом normal Querydict методы по ним.

2. Новый Объект формы не может быть заполнен из обычных request.POST данных, поскольку он будет пустым (если для contentType установлено значение false, как contentType: false , в вызове AJAX). Эти два момента не очень хорошо документированы в Django.

, если contentType равен , оставлен пустым или имеет значение:

contentType: "application/x-www-form-urlencoded",

Затем вы можете получить значения всех отправленных полей ввода с помощью:

first_name = request.POST.get('first_name')
last_name = request.POST.get('last_name') # and so on...

Но здесь я просто использовал простой объект запроса , чтобы заполнить форму в моем views.py

Таким образом, мне пришлось создать представление для обработки запроса AJAX. это представление get_allform_data () (это может быть во многих отношениях, я только что сделал одну версию). В конце концов, все довольно просто, но для обычного разработчика Django это определенно не обычное явление, поэтому о них лучше знать.

так что views.py

from django.template import Template, Context
from django.template.loader import get_template
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse, HttpRequest
from django.urls import reverse
from .forms import NewUserForm
from .models import NewUser
from django.forms import Select, ModelForm
import datetime
from django.views.decorators.csrf import csrf_protect
from django.http import QueryDict
import json
import copy

def index(request):
    return HttpResponse("Hello, world. You're at the myuserform index.")

@csrf_protect
def regform(request):
    title = "This is the Registration Form Page"
    return render(request, 'regform.html', {'title': title})

@csrf_protect
def get_allform_data(request):

    # you can check if request is ajax
    # and you could handle other calls differently
    # if request.is_ajax() - do this and do that...

    # we create an empty Querydict to copy the request into it
    # to be able to handle/modify input request data sent by AJAX
    datam = QueryDict()

    # we should copy the request to work with it if needed
    for i in request:
        datam = copy.copy(i)        

    # the AJAX sent request is better in normal dictionary format
    post_dict = QueryDict(datam).dict()    

    # if this is a POST request we need to process the form data
    if request.method == 'POST':

        # create a form instance and populate it with data from the request:
        # however with using AJAX request.POST is empty - so we use the request Querydict
        # to populate the Form
        form = NewUserForm(post_dict)            

        # check whether it's valid:
        if form.is_valid():
            # you can do whatever with cleaned form data
            data = form.cleaned_data

            # we can now save the form input data to the database
            form.save()

            # print("form is now saved")
            # return HttpResponse("I got the data and saved it")
        else:
            print(form.errors)

    else:
        form = NewUserForm() # this not really needed here, only if we handle the whole in 1 view
        # return HttpResponse("I cannot handle the request yet, since it was not sent yet")
        return HttpResponseRedirect(reverse('regform'))

    return render(request, 'regform.html', {'form' : form })

И то же представление в упрощенном виде, если запрос .POST не пуст:

@csrf_protect
def get_allform_data(request):

    # if this is a POST request we need to process the form data
    if request.method == 'POST':

        # create a form instance and populate it with data from the request:        
        form = NewUserForm(request.POST)

        # check whether it's valid:
        if form.is_valid():
            # you can still do whatever with the cleaned data here
            data = form.cleaned_data

            # and you just save the form (inputs) to the database
            form.save()

        else:
            print(form.errors)

    else:
        form = NewUserForm() # this not really needed here, only if we handle the whole in 1 view
        # return HttpResponse("I cannot handle the request yet, since it was not sent yet")
        return HttpResponseRedirect(reverse('regform'))

    return render(request, 'regform.html', {'form' : form })

И, наконец, urls.py файл

from django.contrib import admin
from django.urls import include, path
from myuserform import views as myuserform_views

urlpatterns = [
    path('', myuserform_views.index),
    path('regform/', myuserform_views.regform, name='regform'),
    path('admin/', admin.site.urls),
    path('get_allform_data/', myuserform_views.get_allform_data)
]

Все это может быть улучшено и расширено намного больше, но, прежде всего, теперь оно выполняет необходимую работу.

И краткое резюме: Вы, конечно, можете пошагово отправлять данные поля ввода в Django (используя те же коды с небольшими изменениями), но в этой конкретной форме это абсолютно не нужно. Суть задачи заключается в следующем: как перемещать вкладки формы с помощью Javascript, одновременно как собирать входные данные и как отправлять данные формы с использованием AJAX в Django для обработки / сохранения входных данных формы в Django база данных. И в то же время мы не хотим обновления страницы.

И на этом скриншоте визуально показана окончательная форма:

image

...