javascript - 如何在 Django 和 AJAX 中正确显示 ValidationError?

标签 javascript jquery python ajax django

在我的 Django 项目中,我有带有表单的模式, super 用户可以在其中创建新用户。

当 super 用户错误地写入现有电子邮件或密码不相似时,我想显示我在 forms.py 文件中设置的 ValidationError

当 super 用户提交有我上面描述的错误的表单时,浏览器会引发错误:

SyntaxError: JSON.parse: unexpected character at line 3 column 1 of the JSON data

Uncaught TypeError: a.replace is not a function
    at Function.htmlPrefilter (jquery.min.js:3)
    at qa (jquery.min.js:3)
    at Ja (jquery.min.js:3)
    at r.fn.init.append (jquery.min.js:3)
    at r.fn.init.<anonymous> (jquery.min.js:3)
    at T (jquery.min.js:3)
    at r.fn.init.html (jquery.min.js:3)
    at Object.error (crud.js:45)
    at i (jquery.min.js:2)
    at Object.fireWith [as rejectWith] (jquery.min.js:2)

问题:当数据无效时如何正确显示错误消息?

表单.py:

class UserCreateForm(UserCreationForm):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'is_active', 'is_superuser', 'password1', 'password2')

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise ValidationError(_("Email already exists."))
        return email

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(_("Enter the same password as above, for verification."))
        return password2

views.py:

class UserCreateView(CreateView):
    template_name = 'users/create_user.html'
    form_class = UserCreateForm

    def get(self, request, *args, **kwargs):
        data = dict()
        user_create_form = UserCreateForm()
        context = {'user_create_form': user_create_form}
        data['html_user_create_form'] = render_to_string(
            'users/create_user.html', context, request=request
        )
        return JsonResponse(data)

    def form_valid(self, form):
        form.save()
        data = dict()
        data['form_is_valid'] = True
        context = {'profiles': Profile.objects.all(),}
        data['html_users'] = render_to_string('users/users.html', context)
        return JsonResponse(data)

JS:

$(function ($) {
    $("#userModalBox").on("submit", ".userCreateForm", function () {
        var form = $(this);
        var dataForm = new FormData(form.get(0));
        $.ajax({
            url: form.attr("action"),
            data: dataForm,
            type: form.attr("method"),
            dataType: 'json',
            success: function (data) {
                if (data.form_is_valid) {
                    $("#loader").show("slow");
                    setTimeout(function() {
                        $("#loader").hide("slow");
                        $("#users").html(data.html_users);
                        $("#users").sortable("refresh");
                        $("#users").sortable("option", "disabled", $("#users .list-group-item").length == 1);
                        $("#userModalBox").modal("hide");
                        $("#userMessageCreate").fadeIn("slow");
                        setTimeout(function() {$("#userMessageCreate").fadeOut("slow");}, 2000);
                        $('#searchUsers').val('');
                    }, 2500);
                }
                else {
                    $("#userModalBox .modal-content").html(data.html_user_create_form);
                }
            },
            error: function (xhr, ajaxOptions, thrownError) {
                $("#userError").fadeIn("slow")
                $("#userError span.error-description").html(thrownError);
                setTimeout(function() {$("#userError").fadeOut("slow");}, 10000);
            },
            cache: false,
            contentType: false,
            processData: false
        });
        return false;
    });
}(jQuery));

模板:

{# START: AJAX ERROR #}
<div class="alert alert-danger alert-dismissible text-center" role="alert" id="userError">
     <i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
    <strong>&nbsp;{% trans "ERROR" %}:</strong><br><span class="error-description"></span>
</div>
{# END: AJAX ERROR #}


{# START: DJANGO ERROR #}
{% if user_create_form.non_field_errors %}
  <div class="well well-error">
    {% for error in user_create_form.non_field_errors %}
      <ul class="list-unstyled">
        <li class="text-danger">
          <i class="fa fa-exclamation-circle" aria-hidden="true"></i>
            <strong>&nbsp;{{ error|escape }}</strong>
          </li>
        </ul>
    {% endfor %}
  </div>
{% endif %}
{# END: DJANGO ERROR #}

编辑部分:

views.py:

def form_invalid(self, form):
        data = dict()
        data['form_is_valid'] = False
        data['form_errors'] = form.errors
        print form.errors
        return JsonResponse(data)

JS:

if (data.form_is_valid) {
   // Some code             
}
else {
   $("#userModalBox .modal-content").html(data.html_user_create_form);
   $('#userModalBox .error-description').html(data.form_errors); <-- DONT WORK???
}

最佳答案

如果您想在 AJAX 响应中返回表单错误,

像这样覆盖 form_invalid:

def form_invalid(self, form):
    error_dict= {'status':'form-invalid','form-errors':form.errors}
    return HttpResponse(json.dumps(error_dict),content_type="application/json")

form.errors:如果 password1 != password2,则获取表单验证错误。 在您的 ajax 成功响应中(“有效和无效的表单将始终返回响应,只有当代码在有效表单中中断时,错误函数才会起作用”)

在您的 AJAX 中:

if (data.status=="form-invalid") {
    Whatever you want to do e.g. 
    $('.class-name').html(data.form-errors)
}

data.status 检查响应中返回的 json-dict 是否有 status="form-errors",然后将这些错误附加到 div 或任何你想要的地方。

注意:Ajax 错误函数仅在没有对请求的响应时才起作用。有效和无效的表单将始终返回一个响应,并将进入 ajax 成功函数,除非代码中出现中断/错误(将不返回任何响应)。

关于javascript - 如何在 Django 和 AJAX 中正确显示 ValidationError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47076009/

相关文章:

javascript - html webview android 中的 Cookie

javascript - 动态选择要打开的模态

javascript - 检测浏览器选项卡/窗口何时处于事件状态

python - 示例 django 和 python 项目

python - 用 python 编写大型 netCDF4 文件?

python - 如何在与应用程序断开连接后释放 Bokeh 服务器(出现错误 : port 5006 is already in use)

javascript - ExpressJS 中的 Promise 返回错误

javascript - 单击来自 sql 数据库的不同消息时,我试图获取 id

javascript - 关于向服务器提交正确数据的 javascript 的安全性

javascript - 在 Chrome 中,触发 $(document).ready() 时不会加载 <embed> 资源。为什么?