使用 django 和 ajax 显示表单错误

Posted

技术标签:

【中文标题】使用 django 和 ajax 显示表单错误【英文标题】:Display form errors with django and ajax 【发布时间】:2016-03-31 04:30:57 【问题描述】:

我有一个联系表格,用户可以通过它联系我。我正在使用带有 ajax 的 django,它工作正常 如果 没有错误。如果在输入字段上方显示任何类似的错误,我想显示错误,而不仅仅是错误,而是输入和错误。但是,它确实区分了 successerror 结果,因为 ajax 请求是成功的。但我需要显示实际的表单错误。我该怎么做?您的帮助将不胜感激。谢谢。

观看次数:

def contact(request):
    if request.is_ajax() and request.POST:
        form = ContactForm(request.POST)
        if form.is_valid():
            new_contact = form.save()
            data = 
                'result': 'success',
                'message': 'Message Sent.'
            
            return JsonResponse(data)
        else:
            data = 
                'result': 'error',
                'message': 'Form invalid',
                'form': 'oops.'
            
            return JsonResponse(data)
    else:
        form = ContactForm()
        return render(request, 'public_contact.html', 
            'form': form
        )

js:

contact_right_form.find('#submit').on('click', function(event) 
    event.preventDefault();
    $.ajax(
        type: contact_right_form.attr('method'),
        url: '/contact/',
        data: contact_right_form.serialize(),
        dataType: 'json',
        success: function(data) 
            if ( data.result == 'success') 
                contact_right_message_sent.text(data.message);
                contact_right_message_sent.show();
            
            else 
                contact_right_message_sent.text(data.message);
                contact_right_message_sent.show();
            
        ,
        error: function() 
            contact_right_message_sent.text('Sorry! Something went wrong.')
        
    );
)

更新

我想在没有 ajax 的情况下显示如下错误:

【问题讨论】:

您的错误信息是否显示? (“出了点问题”)还是您要解决的问题 @Sayse 是的,确实如此。显示Form invalid。我需要显示实际的表单错误。 可以返回form.errors ***.com/questions/2624761/… 【参考方案1】:

举例

django 表单使用 form.errors.as_json() 以 json 格式返回错误。假设:


    "sender": [
         
           "message": "Enter a valid email address.", 
           "code": "invalid"
         
    ],

    "subject": [
          
            "message": "This field is required.", 
            "code": "required"
          
    ]

之后,ajax 得到响应(在success: function(data) 。假设已经成为一个对象:

    data = 
    "sender": [
    
        "message": "Enter a valid email address.", 
      "code": "invalid"
    ,
    
        "message": "Enter a .", 
      "code": "invalid"
    
  ], 
   "subject": [
    
        "message": "This field is required.", 
      "code": "required"
    
  ]
;

并且您已经呈现了以前的表单,假设:

<input type="text" name="sender"> <br>
<input type="text" name="subject"> <br>
<button>Submit</button>

要呈现这些消息,您可以在点击事件中编写脚本:

// in ajax success (event click)
if ($("input").next('p').length) $("input").nextAll('p').empty();
    for (var name in data) 
    for (var i in data[name]) 
      // object message error django
      var $input = $("input[name='"+ name +"']");
      $input.after("<p>" + data[name][i].message + "</p>");
    
  

模拟示例:

// simulation example, Data obtained from ajax response

var data = 
	"sender": [
  	
    	"message": "Enter a valid email address.", 
      "code": "invalid"
    ,
    
    	"message": "Enter a .", 
      "code": "invalid"
    
  ],
	"subject": [
  	
    	"message": "This field is required.", 
      "code": "required"
    
  ]
;

$("button").on("click", function() 
	if ($("input").next('p').length) $("input").nextAll('p').empty();
	for (var name in data) 
    for (var i in data[name]) 
      // object message error django
      var $input = $("input[name='"+ name +"']");
      $input.after("<p>" + data[name][i].message + "</p>");
    
  
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="sender"> <br>
<input type="text" name="subject"> <br>
<button>Submit</button>

【讨论】:

【参考方案2】:

您需要为JsonResponse 定义status_code 参数。

return JsonResponse(data, status_code=400)

这样,它将在 $.ajax 中的 error 回调中结束。

【讨论】:

使用form.errors.as_json(),然后在js端迭代。 但是如何在各个字段上方显示错误?请参阅更新以供参考。 我会明确定义表单字段并在每个字段之前使用像&lt;div class="field-[fieldname]-error"&gt; 这样的smth。然后遍历错误 json 列表(由 ajax 返回)以将消息放入其中。这很容易实现,所以请尝试谷歌搜索。 您也可以通过简单地使用 ajax 渲染整个 html 来避免这一切,因此错误会在后端渲染并发送整个表单 html。这个解决方案网上有很多帮助,所以请先搜索一下。 尝试使用the technique described by Kenneth Love。它使用一些 JS 辅助函数通过 Ajax 以类似于基本 Django 消息的方式处理和呈现表单字段错误。【参考方案3】:

虽然您可以返回所有 json 并将错误添加到字段中,但另一种方法是仅呈现表单的部分模板并将 html 返回给浏览器。然后,您只需将表单替换为返回的表单。

我并不是说这是最好的做法,但这是一种方法。

例如,您有 /form.html 并将其包含在页面中

% include 'form.html' %

然后在你的 form_invalid 方法中,返回渲染的 html 字符串

return render(self.request, 'form.html', 'form' : form, status=500)

然后在你的JS错误方法中,将页面上的表单替换为服务器返回的html。

【讨论】:

以上是关于使用 django 和 ajax 显示表单错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Ajax 渲染 django-crispy-forms 的验证错误?

在 Django 中返回 AJAX 请求的表单错误

使用 django ajax jquery 提交一个文件不起作用的表单

如何让来自 Ajax 的 Django 表单错误出现在用户屏幕上?

将 ajax 与 django 表单一起使用时,出现错误“选择一个有效的选择。这不是可用的选择之一。”

使用Ajax验证并提交Django表单(django-crispy-forms)