2013-06-19 87 views
0

全部,通过ajax验证django formset

我有一个Django视图,内嵌formset。当我正常访问视图并提交时,一切正常。当我通过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以及对话框中的页面。显然,这两个页面上的管理数据不匹配。

所以,我想弄清楚如何防止提交对话框传播到父页面。

+0

在窗体中您是否包含'{{form.management_form}}? – karthikr

+0

@karthikr - 是的,我有。 – trubliphone

回答

1

我结束了改变我的JavaScript显式发送一个适当的值,而不是依靠对话框中的窗体的默认“提交”行为。新代码看起来像这样:

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'); 
    } 
    })