aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/relations.py
diff options
context:
space:
mode:
authorMark Aaron Shirley2013-01-08 08:33:01 -0800
committerMark Aaron Shirley2013-01-08 08:33:01 -0800
commit81691ff9008c69ee02d4a337dc91ddc523c81b6a (patch)
tree99886aa8aacafeec89bc90aa04c616be3429ce5a /rest_framework/relations.py
parenta897eb5480348838b11fdb428ce0d110e8bc8da1 (diff)
parent431ced66e49905fd76db0c36f62794dc3f42470b (diff)
downloaddjango-rest-framework-81691ff9008c69ee02d4a337dc91ddc523c81b6a.tar.bz2
Merge remote-tracking branch 'upstream/master' into null-one-to-one
Diffstat (limited to 'rest_framework/relations.py')
-rw-r--r--rest_framework/relations.py79
1 files changed, 61 insertions, 18 deletions
diff --git a/rest_framework/relations.py b/rest_framework/relations.py
index 6c1d4f5b..5e4552b7 100644
--- a/rest_framework/relations.py
+++ b/rest_framework/relations.py
@@ -4,6 +4,7 @@ from django import forms
from django.forms import widgets
from django.forms.models import ModelChoiceIterator
from django.utils.encoding import smart_unicode
+from django.utils.translation import ugettext_lazy as _
from rest_framework.fields import Field, WritableField
from rest_framework.reverse import reverse
from urlparse import urlparse
@@ -171,6 +172,11 @@ class PrimaryKeyRelatedField(RelatedField):
default_read_only = False
form_field_class = forms.ChoiceField
+ default_error_messages = {
+ 'does_not_exist': _("Invalid pk '%s' - object does not exist."),
+ 'invalid': _('Invalid value.'),
+ }
+
# TODO: Remove these field hacks...
def prepare_value(self, obj):
return self.to_native(obj.pk)
@@ -196,7 +202,10 @@ class PrimaryKeyRelatedField(RelatedField):
try:
return self.queryset.get(pk=data)
except ObjectDoesNotExist:
- msg = "Invalid pk '%s' - object does not exist." % smart_unicode(data)
+ msg = self.error_messages['does_not_exist'] % smart_unicode(data)
+ raise ValidationError(msg)
+ except (TypeError, ValueError):
+ msg = self.error_messages['invalid']
raise ValidationError(msg)
def field_to_native(self, obj, field_name):
@@ -221,6 +230,11 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField):
default_read_only = False
form_field_class = forms.MultipleChoiceField
+ default_error_messages = {
+ 'does_not_exist': _("Invalid pk '%s' - object does not exist."),
+ 'invalid': _('Invalid value.'),
+ }
+
def prepare_value(self, obj):
return self.to_native(obj.pk)
@@ -255,7 +269,10 @@ class ManyPrimaryKeyRelatedField(ManyRelatedField):
try:
return self.queryset.get(pk=data)
except ObjectDoesNotExist:
- msg = "Invalid pk '%s' - object does not exist." % smart_unicode(data)
+ msg = self.error_messages['does_not_exist'] % smart_unicode(data)
+ raise ValidationError(msg)
+ except (TypeError, ValueError):
+ msg = self.error_messages['invalid']
raise ValidationError(msg)
### Slug relationships
@@ -265,6 +282,11 @@ class SlugRelatedField(RelatedField):
default_read_only = False
form_field_class = forms.ChoiceField
+ default_error_messages = {
+ 'does_not_exist': _("Object with %s=%s does not exist."),
+ 'invalid': _('Invalid value.'),
+ }
+
def __init__(self, *args, **kwargs):
self.slug_field = kwargs.pop('slug_field', None)
assert self.slug_field, 'slug_field is required'
@@ -280,8 +302,11 @@ class SlugRelatedField(RelatedField):
try:
return self.queryset.get(**{self.slug_field: data})
except ObjectDoesNotExist:
- raise ValidationError('Object with %s=%s does not exist.' %
+ raise ValidationError(self.error_messages['does_not_exist'] %
(self.slug_field, unicode(data)))
+ except (TypeError, ValueError):
+ msg = self.error_messages['invalid']
+ raise ValidationError(msg)
class ManySlugRelatedField(ManyRelatedMixin, SlugRelatedField):
@@ -300,6 +325,14 @@ class HyperlinkedRelatedField(RelatedField):
default_read_only = False
form_field_class = forms.ChoiceField
+ default_error_messages = {
+ 'no_match': _('Invalid hyperlink - No URL match'),
+ 'incorrect_match': _('Invalid hyperlink - Incorrect URL match'),
+ 'configuration_error': _('Invalid hyperlink due to configuration error'),
+ 'does_not_exist': _("Invalid hyperlink - object does not exist."),
+ 'invalid': _('Invalid value.'),
+ }
+
def __init__(self, *args, **kwargs):
try:
self.view_name = kwargs.pop('view_name')
@@ -336,21 +369,21 @@ class HyperlinkedRelatedField(RelatedField):
slug = getattr(obj, self.slug_field, None)
if not slug:
- raise ValidationError('Could not resolve URL for field using view name "%s"' % view_name)
+ raise Exception('Could not resolve URL for field using view name "%s"' % view_name)
kwargs = {self.slug_url_kwarg: slug}
try:
- return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
+ return reverse(view_name, kwargs=kwargs, request=request, format=format)
except:
pass
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
try:
- return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
+ return reverse(view_name, kwargs=kwargs, request=request, format=format)
except:
pass
- raise ValidationError('Could not resolve URL for field using view name "%s"' % view_name)
+ raise Exception('Could not resolve URL for field using view name "%s"' % view_name)
def from_native(self, value):
# Convert URL -> model instance pk
@@ -358,7 +391,13 @@ class HyperlinkedRelatedField(RelatedField):
if self.queryset is None:
raise Exception('Writable related fields must include a `queryset` argument')
- if value.startswith('http:') or value.startswith('https:'):
+ try:
+ http_prefix = value.startswith('http:') or value.startswith('https:')
+ except AttributeError:
+ msg = self.error_messages['invalid']
+ raise ValidationError(msg)
+
+ if http_prefix:
# If needed convert absolute URLs to relative path
value = urlparse(value).path
prefix = get_script_prefix()
@@ -368,10 +407,10 @@ class HyperlinkedRelatedField(RelatedField):
try:
match = resolve(value)
except:
- raise ValidationError('Invalid hyperlink - No URL match')
+ raise ValidationError(self.error_messages['no_match'])
- if match.url_name != self.view_name:
- raise ValidationError('Invalid hyperlink - Incorrect URL match')
+ if match.view_name != self.view_name:
+ raise ValidationError(self.error_messages['incorrect_match'])
pk = match.kwargs.get(self.pk_url_kwarg, None)
slug = match.kwargs.get(self.slug_url_kwarg, None)
@@ -383,14 +422,18 @@ class HyperlinkedRelatedField(RelatedField):
elif slug is not None:
slug_field = self.get_slug_field()
queryset = self.queryset.filter(**{slug_field: slug})
- # If none of those are defined, it's an error.
+ # If none of those are defined, it's probably a configuation error.
else:
- raise ValidationError('Invalid hyperlink')
+ raise ValidationError(self.error_messages['configuration_error'])
try:
obj = queryset.get()
except ObjectDoesNotExist:
- raise ValidationError('Invalid hyperlink - object does not exist.')
+ raise ValidationError(self.error_messages['does_not_exist'])
+ except (TypeError, ValueError):
+ msg = self.error_messages['invalid']
+ raise ValidationError(msg)
+
return obj
@@ -449,18 +492,18 @@ class HyperlinkedIdentityField(Field):
slug = getattr(obj, self.slug_field, None)
if not slug:
- raise ValidationError('Could not resolve URL for field using view name "%s"' % view_name)
+ raise Exception('Could not resolve URL for field using view name "%s"' % view_name)
kwargs = {self.slug_url_kwarg: slug}
try:
- return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
+ return reverse(view_name, kwargs=kwargs, request=request, format=format)
except:
pass
kwargs = {self.pk_url_kwarg: obj.pk, self.slug_url_kwarg: slug}
try:
- return reverse(self.view_name, kwargs=kwargs, request=request, format=format)
+ return reverse(view_name, kwargs=kwargs, request=request, format=format)
except:
pass
- raise ValidationError('Could not resolve URL for field using view name "%s"' % view_name)
+ raise Exception('Could not resolve URL for field using view name "%s"' % view_name)