如何使用AJAX和jQuery发布Django表单


75

我已经检查了很多有关Django AJAX表单的教程,但是每个教程都告诉您一种实现方式,它们都不是简单的,而且由于我从未使用过AJAX,所以我感到有些困惑。

我有一个名为“ note”的模型,它的模型形式,并且在模板内部,我需要每次note元素发送stop()信号(来自jQuery Sortables)时django更新对象。

我当前的代码:

views.py

def save_note(request, space_name):

    """
    Saves the note content and position within the table.
    """
    place = get_object_or_404(Space, url=space_name)
    note_form = NoteForm(request.POST or None)

    if request.method == "POST" and request.is_ajax:
        msg = "The operation has been received correctly."          
        print request.POST

    else:
        msg = "GET petitions are not allowed for this view."

    return HttpResponse(msg)

JavaScript:

function saveNote(noteObj) {
    /*
        saveNote(noteObj) - Saves the notes making an AJAX call to django. This
        function is meant to be used with a Sortable 'stop' event.
        Arguments: noteObj, note object.
    */
    var noteID = noteObj.attr('id');

    $.post("../save_note/", {
        noteid: noteID,
        phase: "Example phase",
        parent: $('#' + noteID).parent('td').attr('id'),
        title: $('#' + noteID + ' textarea').val(),
        message: "Blablbla",
    });
}

当前代码从模板获取数据并将其打印在终端中。我不知道该如何处理这些数据。我见过有人通过jqueryforms管理数据以将数据发送到django。

如何访问AJAX发送的数据并更新便笺对象?

Answers:


124

由于您使用的是jQuery,为什么不使用以下内容:

<script language="JavaScript">
    $(document).ready(function() {
        $('#YOUR_FORM').submit(function() { // catch the form's submit event
            $.ajax({ // create an AJAX call...
                data: $(this).serialize(), // get the form data
                type: $(this).attr('method'), // GET or POST
                url: $(this).attr('action'), // the file to call
                success: function(response) { // on success..
                    $('#DIV_CONTAINING_FORM').html(response); // update the DIV 
                }
            });
            return false;
        });
    });
</script>

编辑

正如评论中指出的那样,有时上述方法无效。因此,请尝试以下操作:

<script type="text/javascript">
    var frm = $('#FORM-ID');
    frm.submit(function () {
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                $("#SOME-DIV").html(data);
            },
            error: function(data) {
                $("#MESSAGE-DIV").html("Something went wrong!");
            }
        });
        return false;
    });
</script>

谢谢,我可能会使用此解决方案。其他人也可以用,但是我认为这样会更清洁(使用jQuery表单插件可以)
Oscar Carballal 2011年

$(this).serialize()无法捕获submit输入。例如,如果我们在表单中有两个提交按钮!你能告诉我如何处理吗?
Surya

@Sevenearths,在使用ajax post的方法中保存表单数据的同时,我应该使用return render还是HttpResponse,需要澄清

2
首先在你的顶部views.py使用:from django.utils import simplejson。然后做类似的事情returnedJSON['message_type'] = 'success' <newline> returnedJSON['message'] = 'The something saved successfully' <newline> return HttpResponse(simplejson.dumps(returnedJSON), mimetype="application/json")。这样的事情应该起作用
罗伯·约翰斯顿

如果我不想进行frm.serialize怎么办?我想让个人每个字段的frm.values吗?
穆罕默德·塔奇

10

在这种情况下,您可以使用变量名称访问POST请求上的数据:

request.POST["noteid"]
request.POST["phase"]
request.POST["parent"]
... etc

request.POST对象是不可变的。您应该将值分配给变量,然后对其进行操作。

我建议您使用此JQuery插件,以便您可以编写普通的HTML表单,然后将它们“升级”为AJAX。在代码中到处都有$ .post有点乏味。

另外,请使用Firebug(适用于Firefox)或Google Chrome开发人员工具上的“网络”视图,以便您可以查看AJAX呼叫发送的内容。


对于将来从这里来获取答案的人员,将直接从POST对象访问数据的警告警告。确保在验证后使用cleaned_data属性2.2 docs访问数据。不确定op的Django版本如何,但早在1.4.6或更高版本中似乎就一直保持一致。
Clay

4

需要注意的是将表单作为html截取为模态后返回的形式。

Views.py

@require_http_methods(["POST"])
def login(request):
form = BasicLogInForm(request.POST)
    if form.is_valid():
        print "ITS VALID GO SOMEWHERE"
        pass

    return render(request, 'assess-beta/login-beta.html', {'loginform':form})

简单的视图返回被截断的html

表单html剪切

<form class="login-form" action="/login_ajx" method="Post"> 
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h4 class="modal-title" id="header">Authenticate</h4>
  </div>
  <div class="modal-body">
        {%if form.non_field_errors %}<div class="alert alert-danger">{{ form.non_field_errors }}</div>{%endif%}
        <div class="fieldWrapper form-group  has-feedback">
            <label class="control-label" for="id_email">Email</label>
            <input class="form-control" id="{{ form.email.id_for_label }}" type="text" name="{{ form.email.html_name }}" value="{%if form.email.value %}{{ form.email.value }}{%endif%}">
            {%if form.email.errors %}<div class="alert alert-danger">{{ form.email.errors }}</div>{%endif%}
        </div>
        <div class="fieldWrapper form-group  has-feedback">
            <label class="control-label" for="id_password">Password</label>
            <input class="form-control" id="{{ form.password.id_for_label }}" type="password" name="{{ form.password.html_name}}" value="{%if form.password.value %}{{ form.password.value }}{%endif%}">
            {%if form.password.errors %}<div class="alert alert-danger">{{ form.password.errors }}</div>{%endif%}
        </div>
  </div>
  <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<input type="submit" value="Sign in" class="btn btn-primary pull-right"/>
</div>
</form>

包含模态的页面

<div class="modal fade" id="LoginModal" tabindex="-1" role="dialog">{% include "assess-beta/login-beta.html" %}</div>

使用include标记可以加载网页摘要,以便在打开模式时使用。

Modal.js

$(document).on('submit', '.login-form', function(){
$.ajax({ 
    type: $(this).attr('method'), 
    url: this.action, 
    data: $(this).serialize(),
    context: this,
    success: function(data, status) {
        $('#LoginModal').html(data);
    }
    });
    return false;
});

在这种情况下,使用.on()就像.live()一样,键将不是将提交事件绑定到按钮,而是将其绑定到文档。


您的解决方案为我工作,我需要改变的唯一的事情就是data: {}data: $(this).serialize()
Jarrod


2

在服务器端,您的Django代码可以像处理其他表单提交一样处理AJAX帖子。例如,

views.py

def save_note(request, space_name):

    """
    Saves the note content and position within the table.
    """
    place = get_object_or_404(Space, url=space_name)
    note_form = NoteForm(request.POST or None)

    if request.method == "POST" and request.is_ajax():        
        print request.POST
        if note_form.is_valid():
            note_form.save()
            msg="AJAX submission saved"
        else:
            msg="AJAX post invalid"
    else:
        msg = "GET petitions are not allowed for this view."

    return HttpResponse(msg)

我假设您的NoteForm是ModelForm(应该是),因此它具有save方法。请注意,除了添加save()命令之外,我还将您更改request.is_ajaxrequest.is_ajax(),这就是您想要的(如果您使用request.is_ajax代码,则只会检查请求是否具有称为的方法is_ajax)。


1

将AJAX POST与Django表单结合使用的大多数示例,包括官方示例:

https://docs.djangoproject.com/zh-CN/1.9/topics/class-based-views/generic-editing/#ajax-example

ModelForm.clean()没有任何错误(form_valid)的情况下很好。但是,它们执行的工作并不困难:ModelForm通过AJAX响应将错误转换为Javascript / DOM客户端。

我的可插拔应用程序使用AJAX响应路由和客户端视图模型来自动显示基于类的视图AJAX发布ModelForm验证错误,类似于在传统HTTP POST中的显示方式:

https://django-jinja-knockout.readthedocs.org/en/latest/forms.html#ajax-forms-processing https://django-jinja-knockout.readthedocs.org/en/latest/viewmodels.html

Jinja2和Django模板引擎均受支持。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.