【问题标题】:How to prevent validation of Django ModelForm如何防止验证 Django ModelForm
【发布时间】:2016-05-07 05:26:05
【问题描述】:

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

原因是我在该表单中有两个选择字段,并且我使用 Ajax 更改了相关表。 因此,我需要重新加载表单以便能够选择新的/更改的值,并且我不想要所有的验证错误。

编辑:

我最初的计划是设置隐藏字段“刷新”并提交表单(Ajax)。 在 create_component 我想检查刷新的值,并返回渲染但未验证的表单并使用 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
    }

【问题讨论】:

  • 您应该发布有问题的相关代码,或者您尝试过什么。

标签: jquery django validation modelform


【解决方案1】:

如果我在不调用 is_valid 的情况下呈现表单,我会得到一个经过验证的表单

...这听起来不对。

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

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

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

(具体来说,如果您在django/forms/fields.py 中检查BooleanField 的src,他们有一条评论指出“检查字符串'False',这是隐藏字段将为False 提交的内容”)

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

您可能会发现从表单类中删除 refresh 字段更容易(我认为这只是为了您的 hack 的目的),而是手动将 ?refresh=1 查询字符串附加到您的 javascript 中的 POST url。在您看来,这将更容易解析:

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

【讨论】:

  • 这似乎是解决我的问题的最佳方式,它不会弄乱我的 ModelForm 并且可以完美运行!
【解决方案2】:

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

对当前的 url 视图执行 AJAX 发布。然后,您可以使用 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;

}

我希望您可以在此示例的基础上进行构建或使用!

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2012-09-30
      • 2013-11-26
      • 2013-08-22
      • 2011-01-09
      • 1970-01-01
      • 2012-05-23
      • 2011-03-13
      • 1970-01-01
      相关资源
      最近更新 更多