Возврат ошибок формы для запроса AJAX в Django - PullRequest
15 голосов
/ 12 апреля 2010

Я нашел свой путь вокруг Django и jQuery. Я построил базовую форму в Джанго. Нажимая кнопку отправить, я использую jQuery, чтобы отправить AJAX-запрос на сервер для публикации моих данных. Кажется, этот бит работает нормально, и мне удалось сохранить данные. Django возвращает ValidationError, когда форма недействительна. Может кто-нибудь сказать мне, как вернуть этот набор сообщений об ошибках в ответ на мой AJAX-запрос, чтобы я мог легко перебирать его с помощью JS и делать что угодно?

Я нашел этот фрагмент. Глядя на бит JS (processJson), вы увидите, что он, похоже, получает сообщения об ошибках, извлекая их из HTML-ответа. Это кажется мне немного клёвым. Это лучший способ?

Приношу свои извинения за неопределенность.

Заранее спасибо.

Ответы [ 5 ]

11 голосов
/ 22 марта 2012

Этот вопрос старый, но я думаю, что самый короткий ответ мог бы использовать простой json в таком виде.

from django.utils import simplejson

def ajax(request):
    if request.method == 'POST':
        form = someForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponse(something)
        else:
            errors = form.errors
            return HttpResponse(simplejson.dumps(errors))
    else:
        return HttpResponse(something)

теперь вы можете получить доступ к данным в вашем jquery, как Calvin, описанный выше. Jquery облегчает обработку данных. Вы можете сделать что-то вроде этого:

var errors = jQuery.parseJSON(data)
    alert(errors.username)
4 голосов
/ 28 сентября 2011

Ух, прошел год с тех пор, как я видел эту ветку. Что ж, с появлением Django 1.3 и волшебных недокументированных представлений на основе классов стало легче расширять функциональность, связанную с представлением Django. Мой проект, который интенсивно использует базовые представления CRUS, основанные на классах Django, нуждается в функциональности AJAX и JSON. Я добавил пример того, как я изменил представление обновлений Django для поддержки AJAX и возврата ответов AJAX в формате JSON. Посмотрите:

def errors_to_json(errors):
    """
    Convert a Form error list to JSON::
    """
    return dict(
            (k, map(unicode, v))
            for (k,v) in errors.iteritems()
        )

class HybridUpdateView(UpdateView):
    """
    Custom update generic view that speaks JSON
    """
    def form_valid(self, form, *args, **kwargs):
        """
        The Form is valid
        """
        form.save()

        self.message = _("Validation passed. Form Saved.")
        self.data = None
        self.success = True

        payload = {'success': self.success, 'message': self.message, 'data':self.data}

        if self.request.is_ajax():
            return HttpResponse(json.dumps(payload),
                content_type='application/json',
            )
        else:
            return super(HybridUpdateView, self).form_valid(
                form, *args, **kwargs
            )

    def form_invalid(self, form, *args, **kwargs):
        """
        The Form is invalid
        """
        #form.save()

        self.message = _("Validation failed.")
        self.data = errors_to_json(form.errors)
        self.success = False

        payload = {'success': self.success, 'message': self.message, 'data':self.data}

        if self.request.is_ajax():
            return HttpResponse(json.dumps(payload),
                content_type='application/json',
            )
        else:
            return super(HybridUpdateView, self).form_invalid(
                form, *args, **kwargs
            )

Ответ JSON содержит три поля - message (которое читается человеком), data (в этом случае будет список ошибок формы) и success (либо true, либо false, указывая, был ли запрос успешным или нет соответственно.). Это очень легко сделать в клиентской части jQuery. Пример ответа выглядит так:

Content-Type: application/json

{"message": "Validation failed.", "data": {"host": ["This field is required."]}, "success": false}

Это всего лишь пример того, как я сериализовал ошибки формы в JSON и реализовал их в обобщенном представлении на основе классов, но его также можно использовать для работы с обычными представлениями стилей.

1 голос
/ 12 апреля 2010

Когда я использую интерфейсную проверку, обычно ответ содержит фрагменты, к которым вы можете получить доступ через точечную запись (dataReturned.specificData).

На основе того, что и как вы возвращаете данные, является ключом к тому, как получить к ним доступ. Чем более модульно вы обрабатываете возвращаемые данные, тем проще к ним обращаться.

// Start ajax request to server
$.ajax({
    url: '/path_to_service',
    type: 'POST',
    data: { key: value },

    // Do something with the data
    success: function(data) {
        // Data is everything that is returned from the post
        alert(data);
        // data.message could be a piece of the entire return
        alert(data.message);
    } error: function(data) { // Handle fatal errors }
});
0 голосов
/ 17 апреля 2013

Я знаю, что это старый и отвеченный вопрос! Еще хотел бы внести свой вклад. Решение, которое мне нравится больше всего, состоит в том, чтобы использовать декоратор для методов, которые должны выдавать ошибку json.

import traceback,sys,simplejson

def unhandled(e):
  """
     Helper function to format an exception and it's stack
  """
  exc_type, exc_value, exc_traceback = sys.exc_info()
  lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
  stack =  ''.join(line for line in lines)
  return HttpResponse(simplejson.dumps({"error":-1, "response": e.message ,"stack":stack}), content_type='application/json')


def use_json_except(f):
  def new_f(*args):
    try:
      return f(*args)
    except Exception as e:
      return unhandled(e)
    return new_f

Затем вы определяете свой метод Django:

 @use_json_except
 def add_annotation(request):
     ....

Декоратор будет перехватывать любые необработанные исключения и выводить json с информацией об ошибке и стеком.

Лично я считаю это очень хорошим решением для сервера django, который смешивает ответы html и json.

0 голосов
/ 13 апреля 2010

Вы можете использовать мою библиотеку adjax, чтобы справиться с этим для вас. Установите приложение где-нибудь на своем пути, свяжите файл adjax.js и добавьте следующее к вашему виду:

import adjax
@adjax.adjax_response
def my_view(request):
    # prepare my_form with posted data as normal
    adjax.form(request, my_form)

Включить форму с использованием JavaScript после загрузки файла adjax.js:

 $('form').adjaxify();

И наслаждайтесь: -)

Дополнительные функции здесь: http://adjax.hardysoftware.com.au/how/. Я выпустлю версию 1.0 на следующей неделе, дайте мне знать, как идут дела. Проект Google Code находится здесь: http://code.google.com/p/django-adjax/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...