通过ajax验证django formset

时间:2013-06-19 16:46:52

标签: jquery ajax django

所有

我有一个内联formset的Django视图。当我正常访问视图并提交它时,一切正常。但是,当我通过AJAX访问它时,我收到验证错误:

[u'ManagementForm data is missing or has been tampered with']

以下是我的代码的简化版本:

def edit_model(request):
    model_id = request.GET.get('i', None)
    if model_id:
        model = ModelClass.objects.get(pk=model_id)
    else:
        model = ModelClass()

    related_model_formset_class = inlineformset_factory(ModelClass, RelatedModelClass, form=RelatedModelForm,
                                                        prefix="my_related_models")

    if request.method == "GET":
        model_form = ModelFormClass(request.POST, instance=model)
        related_model_formset = related_model_formset_class(request.POST, instance=model)

        if model_form.is_valid() and related_model_formset.is_valid():
            model_form.save()
            related_model_formset.save()

            return HttpResponse("success")
    else:

        model_form = ModelFormClass(instance=model)
        related_model_initial_values = [{"default_value1": 1, "default_value2": 2},
                                        {"default_value1": 1, "default_value2": 2}]
        related_model_formset = related_model_formset_class(instance=model, initial=related_model_intial_values,
                                                            extra=len(related_model_initial_values))

    rendered_form = django.template.loader.render_to_string("my_form.html",
                                                            {"form": model_form, "formset": related_model_formset},
                                                            context_instance=RequestContext(request))
    return HttpResponse(rendered_form, mimetype='text/html')

这可以从另一个页面中的JQuery调用访问(它具有与“my_form.html”类似的结构,带有inline_formsets):

function edit_model(model_id) {

  var url = "http://www.mydomain.com/edit_model/?i=" + model_id

  var edit_model_dialog = $("<div></div>");
  $.ajax({
       url        : url,
       type       : "GET",
       cache      : false,
       success    : function(data) {
          var title = "here is a form to edit the model"
          edit_model_dialog(data);
          edit_model_dialog.dialog({
              title : title,
              modal : true,
              dialogClass: "no-close",
              close   : function() {
                  $(this).dialog("destroy");
              }
          }).dialog('open');
       }
   })

更新

我还没有解决这个问题,但我已经把问题缩小了一点。触发“edit_model”函数的按钮位于另一个页面上,该页面具有自己的窗体和与按钮创建的对话框中呈现的窗体相同类型的窗体集。当在对话框中的表单上按下提交时,它似乎从该父页面触发POST以及对话框中的页面。显然,这两个页面上的管理数据不匹配。

所以,我正在试图弄清楚如何阻止对话框上的提交传播到父页面。

1 个答案:

答案 0 :(得分:1)

我最后更改了我的javascript以显式发送具有适当值的POST,而不是依赖于对话框中表单的默认“提交”行为。新代码看起来像这样:

function edit_model(model_id) {

  var url = "http://www.mydomain.com/edit_model/?i=" + model_id

  var edit_model_dialog = $("<div></div>");
  $.ajax({
     url        : url,
     type       : "GET",
     cache      : false,
     success    : function(data) {
       var title = "here is a form to edit the model"
       edit_model_dialog(data);
       edit_model_dialog.dialog({
         title : title,
         modal : true,
         dialogClass: "no-close",
         close   : function() {
           $(this).dialog("destroy");
         },
         // HERE IS THE NEW BIT...
         buttons : {
           ok : function() {
             // GET THE DATA FROM THE FORM IN THE DIALOG...
             var form_data = $(this).find("the_form").serialize();
             $.ajax({
               url   : url
               // EXPLICITLY SEND IT AS A POST...
               type  : "POST",
               data  : form_data,
               cache : false,
               success : function(data) {
                 if (data == "success") {
                   $(edit_model_dialog).dialog("close");
                 }
                 else {
                   $(edit_model_dialog).html(data);
                 }
               }
             });
           },
           cancel : function () {
             $(edit_model_dialog).dialog("close");
           }
         }
       }).dialog('open');
     }
   })