Возвращаемые ошибки формы для запроса AJAX в Django
Я нашел свой путь вокруг Django и jQuery. Я создал базовую форму в Django. При нажатии submit, я использую jQuery, чтобы сделать запрос AJAX к серверу для отправки моих данных. Этот бит работает нормально, и мне удалось сохранить данные. Django возвращает ValidationError, если форма недействительна. Может ли кто-нибудь сказать мне, как вернуть этот набор сообщений об ошибках в ответ на мой запрос AJAX, чтобы я мог легко перебирать его с помощью JS и делать что-нибудь?
Я нашел этот фрагмент. Глядя на бит JS (processJson), вы увидите, что он, кажется, получает сообщения об ошибках, извлекая их из HTML-ответа. Кажется, это довольно глупо для меня. Это лучший способ сделать это?
Извиняюсь за любую неопределенность.
Спасибо заранее.
Ответы
Ответ 1
Ничего себе, это был год с тех пор, как я увидел эту нить. Что ж, с появлением 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 и реализовал ее в универсальном представлении на основе классов, но может быть использован для работы с обычными представлениями стиля.
Ответ 2
Этот вопрос старый, но я думаю, что самый короткий ответ мог бы использовать простой 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)
Ответ 3
Когда я использую проверку на лицевой стороне, обычно ответ содержит куски, к которым вы можете получить доступ через точечную нотацию (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 }
});
Ответ 4
Вы можете использовать мою библиотеку 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 находится здесь: http://code.google.com/p/django-adjax/
Ответ 5
Я знаю, что это старый и ответивший вопрос! Еще хотел бы внести свой вклад. Решение, которое мне больше всего нравится, - это использовать декоратор для методов, которые должны быть ошибочными json.
import traceback,sys,simplejson
def unhandled(e):
"""
Helper function to format an exception and it 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.