在django中处理单个html表单的多个输入值 [英] Handling multiple input values for single html form in django

查看:151
本文介绍了在django中处理单个html表单的多个输入值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有3个输入和步骤按钮的html表单。




  • 1 st 步骤用户必须放名字和按钮1

  • 2 nd 步骤用户必须输入姓氏并按下按钮2

  • 3 rd 步骤用户必须发送电子邮件并按最终按钮3



每次用户按任意按钮,然后转到下一步html步骤。



我希望在用户按下的任何时候逐步处理我的 views.py 中的输入任何按钮,并非最终提交中的所有内容



我在 views.py中尝试了此代码在django后端获取输入但我在 views.py 中没有得到任何内容(如果我从按钮<更改按钮类型/ code>到提交然后我得到结果坚果刷新页面,我不能去第2步)



views.py



 如果请求中的request.method =='POST'和'first_step':
首席t'1'
firstname = request.POST.get('firstname')
if request.method =='POST'和'second_step'in request.POST:
print'2'
lastname = request.POST.get('lastname')
if request.method =='POST'和'final_step'in request.POST:
print'3'
email = request.POST.get('email')

这是我的html代码:

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

< title>包含圆形标签的表单向导< / 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-tabsrole =tablist>

< li role =presentationclass =active>
< a href =#step1data-toggle =tabaria-controls =step1role =tabtitle =step 1>
< span class =round-tab>
< i class =glyphicon glyphicon-folder-open>< / i>
< / span>
< / a>
< / li>

< li role =presentationclass =disabled>
< a href =#step2data-toggle =tabaria-controls =step2role =tabtitle =step 2>
< span class =round-tab>
< i class =glyphicon glyphicon-pencil>< / i>
< / span>
< / a>
< / li>
< li role =presentationclass =disabled>
< a href =#step3data-toggle =tabaria-controls =step3role =tabtitle =step 3>
< span class =round-tab>
< i class =glyphicon glyphicon-picture>< / i>
< / span>
< / a>
< / li>

< li role =presentationclass =disabled>
< a href =#completedata-toggle =tabaria-controls =completerole =tabtitle =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 activerole =tabpanelid =step1>
< div class =step1>
< div class =row>
< div class =col-md-6>
< label for =exampleInputEmail1>名字< / label>
< input type =emailname =firstnameclass =form-controlid =exampleInputEmail1placeholder =First Name>
< / div>

< / div>

< / div>
< ul class =list-inline pull-right>
< li>< button type =buttonname =first_stepclass =btn btn-primary next-step>保存并继续< / button>< / li>
< / ul>
< / div>
< div class =tab-panerole =tabpanelid =step2>
< div class =step2>

< div class =step-22>
< label for =exampleInputEmail1>姓氏< / label>
< input type =emailname =lastnameclass =form-controlid =exampleInputEmail1placeholder =Last Name>
< / div>
< / div>
< ul class =list-inline pull-right>
< li>< button type =buttonclass =btn btn-default prev-step>上一页< / button>< / li>
< li>< button type =buttonname =second_stepclass =btn btn-primary next-step>保存并继续< / button>< / li>
< / ul>
< / div>
< div class =tab-panerole =tabpanelid =step3>
< div class =step33>


< label for =exampleInputEmail1> email< / label>
< input type =emailname =emailclass =form-controlid =exampleInputEmail1placeholder =Last Name>



< / div>
< ul class =list-inline pull-right>
< li>< button type =buttonclass =btn btn-default prev-step>上一页< / button>< / li>
< li>< button type =buttonname =final_stepclass =btn btn-primary btn-info-full next-step>保存并继续< / button>< / li> ;
< / ul>
< / div>
< div class =tab-panerole =tabpanelid =complete>
< div class =step44>
< h5>已完成< / h5>


< / div>
< / div>
< div class =clearfix>< / div>
< / div>
< / form>
< / div>
< / section>
< / div>
< / div>
< script type =text / javascript>
$(document).ready(function(){
//初始化工具提示
$('。nav-tabs> li a [title]')。tooltip();

//向导
$('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);

});
});

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


//根据菜单

$(文件).ready(function()
{
//将非活动类添加到所有手风琴标题
$('。accordion-header')。toggleClass('inactive-header');

//设置手风琴内容宽度
var contentwidth = $('。accordion-header')。width();
$('。accordion-content')。css({});

//打开第一手风琴当页面加载
$('。accordion-header')。first()。toggleClass('active-header')。toggleClass('inactive-header');
$('。accordion- content')。first()。slideDown()。toggleClass('open-content');

//手风琴效果
$('。accordion-header')。click( function(){
if($(this).is('。inactive-header')){
$('。active-header')。toggleClass('active-header')。toggleClass ('inactive-header')。next()。slideToggle()。toggleClass('open-content');
$(this).toggleClass('activ e-header')。toggleClass('inactive-header');
$(this).next()。slideToggle()。toggleClass('open-content');
}

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

返回false;
});
< / script>
< / body>
< / html>


解决方案

几个小时前我写了这个问题的答案,然后我删除了它,因为我必须意识到我只是部分解决了这个问题,因为这个问题比它的第一个看起来要复杂一点。



正如OP写道:如果你使用 type =submit按钮输入,输入将被提交,但同时页面将刷新,使用此表单,这不是目的。如果您使用 type =button输入,那么输入数据将无法到达服务器(仅当您将提交的数据收集到javascript对象中然后点燃AJAX调用并发送它到具有该AJAX请求的服务器)。



它基本上也不是Django问题,而更像是一个javascript / AJAX调用问题。并且还要调用一些安全问题来解决。由于提交的内容,您还必须以某种方式向服务器发送CSRF令牌。所以,它可以解决,它需要一些时间给任何人。



这个主题的一个很好的来源是:


I have a html form with 3 inputs and steps buttons.

  • 1st step user must put first name and press button 1
  • 2nd step user must put last name and press button 2
  • 3rd step user must put email and press final button 3

Any time the user press any button then go to next html step.

I want to handle inputs in my views.py step by step any time where the user press any button, and not all together in the final submit.

I tried this code in views.py to take inputs in django backend but I don't get anything in views.py (if I change button type from button to submit then I get results nut refresh page and I cant go to step 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')

Here is my html code:

<!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>

解决方案

Few hours ago I wrote an answer to this problem, then I deleted that, because I had to realize that I only partially gave solutions to this problem, since this problem is a bit more complicated than it first looks like.

As the OP wrote: if you use a type="submit" button input, the input will be submitted, but at the same time the page will refresh and with this Form it's not the purpose. And if you use a type="button" input, then the input data will not get to the server (only if you collect the submitted data into a javascript Object and then ignite an AJAX call and send it to the server with that AJAX request).

It's basically also not a Django question, but more like a javascript/AJAX call question. And also invokes a bit of a security questions to solve. Since with the submissions you would also have to send a CSRF token somehow to the server. So, it could be solved, it would take some time to anybody.

A good source about this subject is here: https://simpleisbetterthancomplex.com/tutorial/2016/08/29/how-to-work-with-ajax-request-with-django.html (however, this write-up is in some part, useless in this particular case)

SO THIS IS HOW IT WORKS

A long time ago I have not worked with Django and Python (nowadays more like with PHP and Joomla) but I just pulled up a Django 2.1.3 on Python 3.7 just to make sure this is working (the followings should work in older versions too, with very little modifications if needed)

I created an app called 'myuserform' and first created a Model in 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

Then I created a Form in forms.py (important: please create a Model first, then a ModelForm in Django if you create Forms in Django - that is the way how you should do these jobs right)

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']

Since, the HTML Form was already given by the OP here above, then I just created two templates from them in the templates folder of my app 'myuserform'. A base.html and a regform.html (I was not concerned about creating nice templates now)

  1. I had to rename the input fields(name) of the HTML form to be compatible with my Django Form and Model(the input fields' names should be the same as the Django Form fields' and Model fields' names).

I also cleared a bit the input fields to make them work well with javascript codes with adding an onclick attribute to the buttons which ignites different custom javascript functions (this could be very much simplified with jQuery element selections of course). The last button will submit the form via AJAX. (you do not have to send or collect the input data separately to Django, it's redundant according to me - since what do you want to do with a firstname input data which is for example "Joe" ? Nothing). You can also pre-validate the input data step by step with javascript - I added those functions too, however these pre-validate functions could be extended more. Now, it only checks whether the field is empty or not, and the email field is a valid email format input or not and it does not let you further if it is not).

  1. Now this is an important part. The templates of course should be created with Django style tags, and custom javascript files should be imported from a created js folder. I just copy here the HTML templates from Django. One important thing is that I placed a secure csrf token into the given HTML form and I wrote few added javascript/jquery code in the script part of the HTML. And the second most important part is the javascript function I wrote, called function sendNuData(), which is sending the Form input data to the Django view with using an AJAX call.

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 %}

Then one of the hardest part, which is the question of how to handle/or save AJAX calls data sent to Django from a Form submission (so the Form is not submitted via a normal submit button (with normal HTTP request), which would be a very well known, relatively easy case and task to handle).

There will be 2 things you will find yourself up against when you submit and send html form input data via an AJAX call to Django:

1. The request data is going to be in WSGI Request object, otherwise, immutable Querydict format, which could not be handled by just calling normal Querydict methods on them.

2. The new Form object cannot be populated from usual request.POST data, since it will be empty (if the contentType set to false, like contentType: false, in the AJAX call). These two points are not very well documented in Django.

if the contentType is left empty or is set to:

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

Then you can get the values of all the submitted input fields with:

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

But here I just used the plain request object to populate the Form in my views.py

Thus I had to create a view to handle the AJAX request. it is the get_allform_data() view (it could be in many ways, I just made one version). It's quite simple at the end, but it's definitely not an everyday thing for a normal Django developer, so it's better to know about these.

so the 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 })

And the same view in simplified form if the request.POST is not empty:

@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 })

And finally the urls.py file

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)
]

The whole thing could be improved and extended much more but first and foremost it does the required job now.

And the short summary: you can of course send input field data step by step to Django (using the same codes with little modifications), but at this particular Form it is absolutely unnecessary. The point of the task is: how to move Form tabs with Javascript, at the same time how to collect input data, and how to send Form data using AJAX to Django to handle/save Form input data to Django database. And at the same time we do not want page refresh.

And this screenshot shows the final Form visually:

这篇关于在django中处理单个html表单的多个输入值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆