This commit is contained in:
Krzysztof Nazarewski 2016-06-06 11:06:08 +00:00
commit ec3b19f593
3 changed files with 20 additions and 2 deletions

View File

@ -64,7 +64,7 @@ def is_simple_callable(obj):
return len_args <= len_defaults return len_args <= len_defaults
def get_attribute(instance, attrs): def get_attribute(instance, attrs, required=True):
""" """
Similar to Python's built in `getattr(instance, attr)`, Similar to Python's built in `getattr(instance, attr)`,
but takes a list of nested attributes, instead of a single attribute. but takes a list of nested attributes, instead of a single attribute.
@ -82,6 +82,12 @@ def get_attribute(instance, attrs):
instance = getattr(instance, attr) instance = getattr(instance, attr)
except ObjectDoesNotExist: except ObjectDoesNotExist:
return None return None
# RelatedObjectDoesNotExist inherits from both ObjectDoesNotExist and
# AttributeError, so ObjectDoesNotExist has to come first
except (AttributeError, KeyError):
if not required:
raise SkipField
raise
if is_simple_callable(instance): if is_simple_callable(instance):
try: try:
instance = instance() instance = instance()

View File

@ -154,7 +154,7 @@ class RelatedField(Field):
pass pass
# Standard case, return the object instance. # Standard case, return the object instance.
return get_attribute(instance, self.source_attrs) return get_attribute(instance, self.source_attrs, self.required)
@property @property
def choices(self): def choices(self):

View File

@ -340,6 +340,18 @@ class PKForeignKeyTests(TestCase):
serializer = NullableForeignKeySourceSerializer() serializer = NullableForeignKeySourceSerializer()
self.assertEqual(serializer.data['target'], None) self.assertEqual(serializer.data['target'], None)
def test_foreign_key_not_required(self):
"""
Let's say we wanted to fill the non-nullable model field inside
Model.save(), we would make it empty and not required.
"""
class ModelSerializer(ForeignKeySourceSerializer):
class Meta(ForeignKeySourceSerializer.Meta):
extra_kwargs = {'target': {'required': False}}
serializer = ModelSerializer(data={'name': 'test'})
serializer.is_valid(raise_exception=True)
self.assertNotIn('target', serializer.data)
class PKNullableForeignKeyTests(TestCase): class PKNullableForeignKeyTests(TestCase):
def setUp(self): def setUp(self):