【问题标题】:How to POST a django form with AJAX & jQuery如何使用 AJAX 和 jQuery 发布 django 表单
【发布时间】:2011-11-12 05:48:06
【问题描述】:

我查看了大量关于 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 发送的数据并更新 note 对象?

【问题讨论】:

    标签: javascript jquery ajax django django-templates


    【解决方案1】:

    既然您使用的是 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>
    

    编辑

    正如 cmets 中所指出的,有时上述方法不起作用。所以尝试以下方法:

    <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 表单插件)
    • $(this).serialize() 无法捕获 submit 输入。例如,如果我们在一个表单中有两个提交按钮!能告诉我怎么处理吗?
    • @Sevenearths,在使用 ajax post 的方法中保存表单数据时,我应该使用返回渲染还是 HttpResponse,需要说明
    • 首先在您的views.py 顶部使用:from django.utils import simplejson。然后执行returnedJSON['message_type'] = 'success' &lt;newline&gt; returnedJSON['message'] = 'The something saved successfully' &lt;newline&gt; return HttpResponse(simplejson.dumps(returnedJSON), mimetype="application/json") 之类的操作。类似的东西应该可以工作
    • 如果我不想frm.serialize怎么办?我想获取每个字段的个人 frm.values?
    【解决方案2】:

    在Django表单中使用AJAX POST的大部分示例,包括官方示例:

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

    ModelForm.clean() 没有产生任何错误 (form_valid) 时很好。 但是,它们并不执行困难的部分:通过 AJAX 响应将 ModelForm 错误翻译到 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 模板引擎。

    【讨论】:

      【解决方案3】:

      需要注意的是,将表单作为 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>
      

      使用包含标签加载页面加载时的片段,以便在打开模式时可用。

      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()
      【解决方案4】:

      由于其他答案确实有效,我更喜欢使用jQuery Form Plugin。它完全支持您想要的以及更多。 post 视图在 Django 部分中照常处理,只返回被替换的 HTML。

      【讨论】:

        【解决方案5】:

        在服务器端,您的 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() 命令之外,我还将您的request.is_ajax 更改为request.is_ajax(),这就是您想要的(如果您使用request.is_ajax,您的代码将只检查请求是否有一个名为is_ajax 的方法,显然它确实如此)。

        【讨论】:

          【解决方案6】:

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

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

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

          我建议您使用this JQuery plugin,这样您就可以编写普通的 HTML 表单,然后将它们“升级”到 AJAX。在你的代码中到处都有 $.post 有点乏味。

          另外,使用 Firebug 上的网络视图(用于 Firefox)或 Google Chrome 的开发者工具,这样您就可以查看 AJAX 调用发送的内容。

          【讨论】:

          • 对于那些将来来这里寻求答案的人直接从 POST 对象访问数据的公平警告。确保您在验证后使用cleaned_data 属性2.2 docs 访问数据。不确定 op 的 Django 版本,但它似乎可以追溯到 1.4.6 或更高版本。
          猜你喜欢
          • 2011-05-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-08
          • 1970-01-01
          • 2011-08-09
          • 1970-01-01
          • 2016-12-14
          相关资源
          最近更新 更多