如何防止 Django ModelForm 的验证

How to prevent validation of Django ModelForm

有没有办法阻止对提交的 Django ModelForm 进行验证?

原因是我在该表单中有两个 select 字段,我使用 Ajax 更改了相关的 table。 因此,我需要重新加载表单才能 select new/changed 值,我不想要所有验证错误。

编辑:

我最初的计划是设置隐藏字段 "refresh" 并提交表单 (Ajax)。 在 create_component 中,我想检查刷新的值,return 呈现但未验证的表单并使用 jQuery 替换它。 我希望 form.is_valid() 触发验证过程,但不幸的是,如果我在不调用 is_valid.

的情况下呈现表单,我会得到一个经过验证的表单

views.py

def create_component(request):
  if request.method == "POST":
    form = ComponentForm(request.POST)
    if request.POST.get('refresh',False):
      return render(request, "component_form.html", {"form":form})
    if form.is_valid():
      form.save()
      return redirect("material")
  else:
    form = ComponentForm()
  return render(request, "create_component.html", {"form":form})

forms.py

class ComponentForm(ModelForm):
  refresh = BooleanField(widget=HiddenInput, required=False)
  class Meta:
    model = Component
    fields = ['name', 'articlenumber', 'manufacturer', 'vendor', 'price', 'picture', 'notes']
    labels = {
      'name': _('Bezeichnung'),
      'manufacturer': _('Hersteller'),
      'articlenumber': _('Artikelnummer'),
      'vendor': _('Lieferant'),
      'price': _('Preis'),
      'notes': _('Notizen')
    }
    widgets = {
      'picture': HiddenInput
    }

您可以使用 Django 错误消息:https://docs.djangoproject.com/en/1.9/ref/contrib/messages/#adding-a-message

对当前 url 视图执行 AJAX post。然后,您可以使用 AJAX 请求并在表单内的 div 或 p 中显示表单错误。无需刷新。 这是一个使用 AJAX、Django 1.9 和 Python 2.7:

插入注释的示例

forms.py:

#comment form
class InsertComentForm(forms.Form):
    comment = forms.CharField(widget=forms.Textarea(attrs={'id': 'comment', 'placeholder': 'Enter a Comment'}),required = True)

views.py:

#inside comment view
InsertComent = forms.InsertComentForm()     
if request.is_ajax():        
    if request.method == 'POST':
        InsertComent = forms.InsertComentForm(request.POST)            
        if request.POST.get("InsertCommentSubmit") is not None: #error            
            if request.POST.get("comment")=="":
                message = "Comment field cannot be empty!"

                return HttpResponse(message)                           

            elif User.objects.filter(username = request.user.username).exists():        
                if InsertComent.is_valid():
                    article_id = Article.objects.get(title=Slug, pub_date= aTimestamp).pk
                    article_id = article_id
                    user_id = request.user.id

                    p=Comment(comment=InsertComent.cleaned_data['comment'], article_id=article_id, user_id=user_id, date=date.today(), flagged=0, ipAddress=get_ip(request))
                    p.save()

                    message="Thanks for commenting!"                                  
                    return HttpResponse(message)    
            else:
                 messages.error(request,  "Login to Comment!"); 
    else:
        message = "Not Ajax"
        return HttpResponse(message)   

模板:

       <form id="commentForm" class="col-md-12 djangoForm" action="" method="POST">
            <p class="formMessage" id="error_msg_comment"> </p><!-- Needs Space for style, AJAX Errors Here-->                          
        <div class="fieldWrapper">
            <input type="hidden" name="csrfmiddlewaretoken" id="csrfmiddlewaretoken" value="{{ csrf_token }}">
        </div>
        <div class="fieldWrapper">
            {{ InsertComentForm.comment }}
        </div>

       <input id="InsertCommentSubmit" name="InsertCommentSubmit" class="Button" type="submit" class="btn btn-default" value="Send" onclick="return InsertCommentForm()"/>           
       </form>

AJAX:

//Do not forget to pass the csrfmiddlewaretoken!
function InsertCommentForm(){
    var comment=document.getElementById('comment').value; //change from name to id!
    var csrfmiddlewaretoken=document.getElementById('csrfmiddlewaretoken').value; //change from name to id!    
    var InsertCommentSubmit=document.getElementById('InsertCommentSubmit').value;//change from name to id!

    var dataString = 'comment='+ comment+ 
        '&csrfmiddlewaretoken='+ csrfmiddlewaretoken + 
        '&InsertCommentSubmit='+ InsertCommentSubmit;
    $.ajax({

        type: "post",
        url : "",
        data:dataString,
        cache:false,
        success: function(html){
            if (html==0){
                window.location.reload();              
                //document.getElementById("commentForm").reset();                
            }else{
                $('#error_msg_comment').html(html);              

            }         
        }

    });
    return false;

}

我希望您可以借鉴或使用这个例子!

我终于找到了适合我需要的解决方案。 我使用 Ajax 调用提交表单,从响应中取出更新后的 select 并将原来的 select 替换为:

$("#id_refresh").val(1);
$.post(
    $("form").attr("action"),
    $("form").serialize(),
    function(d) {
        $("#id_manufacturer").replaceWith($(d).find("#id_manufacturer"));
        $("#id_refresh").val(0);
    }
);

这可能是一种 hacky 的方式,但它对我有用。

I get a validated form if I render the form without calling is_valid

...这对我来说听起来不对。

我认为你的实际问题在这里:

if request.POST.get('refresh',False):

...当像这样检查原始 post var(未经您的表单处理)时,该值将始终是一个字符串,因此它将始终与 True

进行比较

(具体来说,如果您在 django/forms/fields.py 中检查 BooleanField 的 src,他们会有一条评论指出 "check for the string 'False', which is what a hidden field will submit for False"

所以您获得经过验证的表单的原因是因为您的代码遵循 form.is_valid 代码路径。

您可能会发现从表单 class 中删除 refresh 字段(我认为这只是您的 hack 所需的),而不是手动附加 ?refresh=1 querystring 更容易从您的 javascript 到 POST url。这在您看来更容易解析:

if int(request.GET.get('refresh', '0')):