在 django 中处理单个 html 表单的多个输入值

Posted

技术标签:

【中文标题】在 django 中处理单个 html 表单的多个输入值【英文标题】:Handling multiple input values for single html form in django 【发布时间】:2019-04-02 17:58:14 【问题描述】:

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

1st 步骤用户必须输入名字并按下按钮 1 2nd 步骤用户必须输入姓氏并按下按钮 2 3rd 步骤用户必须输入电子邮件并按下最终按钮 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>

【问题讨论】:

我需要你的工作版本,获取静态表单数据有不同的方法。 @sorabh86 django 1.11 版本 python 2.7 有什么特别的原因为什么不“在最终提交中不在一起”。 ? 【参考方案1】:

几个小时前我写了一个关于这个问题的答案,然后我删除了它,因为我不得不意识到我只是部分地给出了这个问题的解决方案,因为这个问题比最初看起来要复杂一些。

正如 OP 所写:如果您使用 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),但我只是在 Python 3.7 上提取了一个 Django 2.1.3 以确保这是工作(以下也应该在旧版本中工作,如果需要,只需很少的修改)

我创建了一个名为“myuserform”的应用,并首先在 models.py

中创建了一个 Model

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 中创建了一个表单(重要:如果您在 Django 中创建表单,请先创建一个模型,然后在 Django 中创建一个 ModelForm - 这就是您应该如何正确完成这些工作的方式)

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

由于上面的 OP 已经给出了 HTML 表单,所以我只是在我的应用程序“myuserform”的 templates 文件夹中从它们创建了两个模板。一个 base.html 和一个 regform.html(我现在不关心创建漂亮的模板)

    我不得不重命名 HTML 表单的输入字段(名称)以与我的 Django 表单和模型兼容(输入字段的名称应该与 Django 表单字段和模型字段的名称相同)。

我还清除了一些输入字段,使它们与 javascript 代码一起工作,并为按钮添加了一个 onclick 属性,该属性可触发不同的自定义 javascript 函数(这可以使用 jQuery 元素进行非常简化当然是选择)。 最后一个按钮通过 AJAX 提交表单。(您不必单独向 Django 发送或收集输入数据,这对我来说是多余的 - 因为你做什么想要处理名字输入数据,例如 "Joe" ? 无)。您还可以使用 javascript 逐步预验证输入数据 - 我也添加了这些功能,但是这些预验证功能可以扩展更多。现在,它只检查该字段是否为空,并且电子邮件字段是否为有效的电子邮件格式输入,如果不是,它不会让您进一步)。

    现在这是一个重要的部分。 templates 当然应该使用 Django 样式标签创建,并且应该从创建的 js 文件夹 导入自定义 javascript 文件。我只是在这里复制来自 Django 的 HTML 模板。一件重要的事情是我在给定的 HTML 表单 中放置了一个安全的 csrf 令牌,并且我在 HTML 的脚本部分编写了一些添加的 javascript/jquery 代码。 第二个最重要的部分是我编写的javascript函数,称为function sendNuData(),它将表单输入数据发送到Django视图 使用AJAX 调用。

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>

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 %

然后是最困难的部分之一,这是如何处理/或保存从表单提交发送到 Django 的 AJAX 调用数据的问题 strong>(因此表单不是通过普通的提交按钮(使用普通的 HTTP 请求)提交的,这将是一个众所周知的、相对容易处理的案例和任务)。

会有两件事当您通过 AJAX 调用向 Django 提交和发送 html 表单输入数据时,您会发现自己遇到了挑战:

1.请求数据为WSGI请求对象,否则为不可变Querydict格式,无法处理只是对它们调用普通的 Querydict 方法。

2. 新的 Form 对象 无法从通常的 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 )

如果 request.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移动Form标签,同时如何收集输入数据,以及如何使用AJAX将Form数据发送到Django处理/保存Form输入数据到Django 数据库。同时我们不希望页面刷新。

这个截图直观地展示了最终的表单:

【讨论】:

您了解我需要的问题,但我不知道 javascript/AJAX 在服务器中发送输入,为此我请教如何构建该任务 很快(可能是今晚)我会用你需要的代码示例更新我的答案。 使用 AJAX 响应是最好的选择,您可以将值和 CSRF 令牌发布到视图并相应地使用【参考方案2】:

一种可能且未经测试的解决方案是使您的模型的属性可以为空/为空。如下所示保存帖子对象的相关属性。因此,您可以为每个 if 条件一一设置属性,而不会出现任何空/空白错误。此外,如果您不想每次点击都刷新页面,您可以使用 AJAX。

每次点击都在view 中设置variable=buttonIdif 条件,例如if variable == 0,并且每次都将按钮的数值作为参数传递给视图,用于view(request, buttonId) 等if 条件,保存对象的相关属性,然后重定向到具有相同视图的下一个 HTML`。

【讨论】:

你的建议是创建更多视图来逐步处理输入?你能给我看一些这个任务的例子吗?或者如果很容易用 AJAX 给我展示一下 AJAX 只有一个视图,三个 if 条件动态获取按钮 id 并根据 id 决定应用哪个步骤。当您单击第一个按钮时,您会将该按钮的 ID 和表单发送到您的视图,例如 view(request , buttonId) 并在您的视图中设置三个步骤的 if 条件,您将拥有三个 if,例如 if buttonId == 1 然后 self.firstname= firstname,保存数据并返回到第二个 html 或具有下一步所需上下文的相同 html。因此,您不必编写任何 JavaScript 或 Ajax。因为每一步都会部分保存对象的数据,直到最后一步。 这仍然会导致页面刷新,因为他正在使用带有表单数据的输入/提交按钮。【参考方案3】:

我想我知道你想去哪里,但正如其他用户已经说过的那样,这不是 Django 问题,而更像是一个设计问题。

基本上,当您尝试通过提交将信息发布到服务器时,您总是会碰壁。如果你想要这个功能,你需要使用 AJAX。

除此之外,您还有两个真正的选择:

    在 javascript 中构建一个状态解决方案,该解决方案将通过步骤 1 和 2 跟踪表单信息,然后在步骤 3 完成时 POST 表单数据。 使用 AJAX 构建异步解决方案以将部分数据发布到您的服务器(这将需要更新视图代码以接受部分数据而不是整个 Django 模型)。

Here is a place where you can learn how to use jQuery to accomplish suggestion number 2.

【讨论】:

【参考方案4】:

在这个问题中,我并不完全清楚期望的行为是什么。正如有人指出的那样,这可能是一个设计问题。

通过“逐步处理我的views.py 中的输入”,在我看来,每个步骤都需要发布数据并由后端处理? (ajax 与否)

如果希望在没有 ajax 的情况下对每个步骤都有一个响应后循环,则前面的步骤需要成为返回的上下文/模板的一部分,并且可以在后端“处理”该步骤。

对于这种情况有一个非常强大的工具,django 中的FormWizard,它可能会给您一些具体解决方案的灵感?

【讨论】:

以上是关于在 django 中处理单个 html 表单的多个输入值的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 django 中的单个表单中使用多个表单集,如果可以的话如何?

Django 表单:查询结果定义的字段,单个视图同时更新多个对象

django:csrf_token 用于单个页面上的多个表单和 ajax 请求

Django 在基于类的视图中处理多个表单

django - 在一个帖子请求中提交多个表单(与一键不同,因为我需要一起处理这两个表单的数据!)

Django如何为多个表单创建一个帖子请求。