Как вернуть ошибки проверки формы Django через Ajax - PullRequest
1 голос
/ 11 ноября 2019

Я пытался в течение нескольких недель увидеть, как я возвращаю ошибки проверки, определенные в моем forms.py, и передаю их Ajax, я видел пару решений в Интернете, и их версии Django либо слишком стары, либо коды Django и JSслишком сложно. Я хочу, чтобы кто-то помог мне с использованием примеров кода, чтобы продемонстрировать, как это достижимо. Я хочу, чтобы на моей веб-странице отображались как сообщения об ошибках, поступающих из Django, так и сообщение об успехе. Вот что я сделал до сих пор.

forms.py

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

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

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

    def clean(self):
        cleaned_data = super().clean()
        email = cleaned_data.get('email')
        vmail = cleaned_data.get('vemail')

        if email != vmail:
            raise forms.ValidationError('Your first email and second email must match')
        elif not email.endswith('@alabiansolutions.com'):
            raise forms.ValidationError('Please we need alabiansolution email')

views.py

from django.shortcuts import render
from django.views.generic import ListView, View, CreateView
from ajax_app.forms import UserCreateForm
from django.urls import reverse_lazy 

# Create your views here.
def user_create_view(request):
    if request.method == 'POST':
        user_form = UserCreateForm(request.POST)
        if user_form.is_valid():
            user_form.save()
    else:
        user_form = UserCreateForm()
    return render(request, 'ajax_app/index.html', {'user_create_form':user_form})

urls.py

from django.contrib import admin
from django.urls import path
from ajax_app import views 

urlpatterns = [
    path('',  views.user_create_view, name='user_create_view'),
]

index.html

{% 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 %}
        <h3>Add Data</h3>
       <form id="addUser" action="{% url 'user_create_view' %}" method="POST">
        <table>
            {{ user_create_form.as_table}}
        </table>
        {% csrf_token %}
        <button type="submit" class="btn btn-primary">Submit</button>
    </form>

script.js

// Create Django Ajax Call
$("form#addUser").submit(function() {
        var form = $("#addUser");
        // Create Ajax Call
        $.ajax({
            url: form.attr("action"),
            data: form.serialize(),
            dataType: 'json',
            success: function (data) {
                // I don't know next step
            }
        });

    $('form#addUser').trigger("reset");
    return false;
});

Ответы [ 2 ]

1 голос
/ 11 ноября 2019

urls.py

from django.contrib import admin
from django.urls import path
from ajax_app import views 

urlpatterns = [
    path('',  views.index, name='index'),
    path('ajax_form/',  views.ajax_submit, name='ajax_submit'),
]

forms.py

from django.utils.translation import ugettext_lazy as _
from django import forms


class MyForm(forms.Form):

    name = forms.CharField(
        label=_('Name'),
        max_length=255,
        required=True,
        widget=forms.TextInput(
            attrs={'class': 'form-control', 'name': 'name', }
        )
    )

    email = forms.EmailField(
        label=_('Email'),
        max_length=255,
        required=True,
        widget=forms.EmailInput(
            attrs={'class': 'form-control', 'name': 'email', }
        )
    )

    def clean_email(self):

        email = self.cleaned_data['email']
        # Validation Example
        if email != 'hi@hi.com':
            raise forms.ValidationError("Email already exists.")

        return email

view.py

from django.shortcuts import render
from django.http import QueryDict
from .forms import *


def index(request):
    """
    Show Inital Form
    :param request:
    :return:
    """
    form = MyForm()

    return render(request, 'ajax_app/index.html', {'form': form})


def ajax_submit(request):
    """
    Ajax call
    :param request:
    :return:
    """
    if request.method == 'POST':

        form_data = QueryDict(request.POST['form'].encode('ASCII'))

        form = MyForm(form_data)
        if form.is_valid():
            name = form.cleaned_data.get('name', None)
            # Do some here

    return render(request, 'ajax_app/form.html', {'form': form})

form.html

<div class="form-group {% if form.name.errors %}has-error{% endif %}">
  {{ form.name.label_tag }}
  {{ form.name }}
  {% if form.name.help_text %}
    <span class="help-block">{{ form.name.help_text }}</span>
  {% endif %}
  {% for error in form.name.errors %}
    <span class="help-block">{{ error }}</span>
  {% endfor %}
</div> <!-- form-group -->

<div class="form-group {% if form.email.errors %}has-error{% endif %}">
  {{ form.email.label_tag }}
  {{ form.email }}
  {% if form.email.help_text %}
    <span class="help-block">{{ form.email.help_text }}</span>
  {% endif %}
  {% for error in form.email.errors %}
    <span class="help-block">{{ error }}</span>
  {% endfor %}
</div> <!-- form-group -->

или

<table>
    {{ form.as_table}}
</table>

index.html

...
<h3>Add Data</h3>
<form id="addUser" action="{% url 'ajax_submit' %}" method="POST">
  {% csrf_token %}
  <div class="form-container">
    {% include "ajax_app/form.html" %}
  </div>

  <button type="submit" class="btn btn-primary">Submit</button>
</form>
...

Ajax

Этот скрипт должен быть выполнен после загрузки jquery

$("form#addUser").submit(function(e) {
  e.preventDefault(); // <--

  var csrftoken = jQuery('[name=csrfmiddlewaretoken]').val();
  var form = $("#addUser");

  $.ajax({
    method: form.attr("method"),
    url: form.attr("action"),
    data: {
        csrfmiddlewaretoken: csrftoken,
        form: form.serialize()
    },
    dataType: 'Html',
    success: function (data) {
        $('.form-container').html(data);  // <--
    }
});
1 голос
/ 11 ноября 2019

Проверка формы не может быть показана ajax напрямую. Однако вы можете вызвать ошибку HTTP вместо ошибки проверки, а затем показать ее в функции ошибки ajax. Вот пример: -

Подход 1:

# Return this instead of validation error
return HttpResponse('Error text', status=HTTP_404_NOT_FOUND)

# Ajax error method which will come after success method
error: function(jqXHR, exception) 
    alert(jqXHR.responseText);
}

Подход 2:

# Return Json Resposne instead of validationerror
return JsonResponse({'error': True, 'message': 'text'})

#Ajax success function
success: function(data) {
   if (data.hasOwnProperty('error')) {
        if (data.error==true) {
          alert(data.message);
        }
      }
  }, 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...