Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Errors in browsable API on error. #3179

Merged
merged 3 commits into from
Jul 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions rest_framework/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.utils.translation import ungettext

from rest_framework import status
from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList


def _force_text_recursive(data):
Expand All @@ -22,14 +23,20 @@ def _force_text_recursive(data):
lazy translation strings into plain text.
"""
if isinstance(data, list):
return [
ret = [
_force_text_recursive(item) for item in data
]
if isinstance(data, ReturnList):
return ReturnList(ret, serializer=data.serializer)
return data
elif isinstance(data, dict):
return dict([
ret = dict([
(key, _force_text_recursive(value))
for key, value in data.items()
])
if isinstance(data, ReturnDict):
return ReturnDict(ret, serializer=data.serializer)
return data
return force_text(data)


Expand Down
2 changes: 1 addition & 1 deletion rest_framework/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ def is_valid(self, raise_exception=False):
self._errors = {}

if self._errors and raise_exception:
raise ValidationError(self._errors)
raise ValidationError(self.errors)

return not bool(self._errors)

Expand Down
4 changes: 2 additions & 2 deletions rest_framework/utils/serializer_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __repr__(self):
))

def as_form_field(self):
value = force_text(self.value)
value = '' if self.value is None else force_text(self.value)
return self.__class__(self._field, value, self.errors, self._prefix)


Expand Down Expand Up @@ -100,7 +100,7 @@ def as_form_field(self):
if isinstance(value, (list, dict)):
values[key] = value
else:
values[key] = force_text(value)
values[key] = '' if value is None else force_text(value)
return self.__class__(self._field, values, self.errors, self._prefix)


Expand Down
20 changes: 20 additions & 0 deletions tests/test_generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,16 @@ def test_post_cannot_set_id(self):
created = self.objects.get(id=4)
self.assertEqual(created.text, 'foobar')

def test_post_error_root_view(self):
"""
POST requests to ListCreateAPIView in HTML should include a form error.
"""
data = {'text': 'foobar' * 100}
request = factory.post('/', data, HTTP_ACCEPT='text/html')
response = self.view(request).render()
expected_error = '<span class="help-block">Ensure this field has no more than 100 characters.</span>'
self.assertIn(expected_error, response.rendered_content.decode('utf-8'))


EXPECTED_QUERIES_FOR_PUT = 3 if django.VERSION < (1, 6) else 2

Expand Down Expand Up @@ -282,6 +292,16 @@ def test_patch_cannot_create_an_object(self):
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertFalse(self.objects.filter(id=999).exists())

def test_put_error_instance_view(self):
"""
Incorrect PUT requests in HTML should include a form error.
"""
data = {'text': 'foobar' * 100}
request = factory.put('/', data, HTTP_ACCEPT='text/html')
response = self.view(request, pk=1).render()
expected_error = '<span class="help-block">Ensure this field has no more than 100 characters.</span>'
self.assertIn(expected_error, response.rendered_content.decode('utf-8'))


class TestFKInstanceView(TestCase):
def setUp(self):
Expand Down