summaryrefslogtreecommitdiff
path: root/django/core/serializers/python.py
diff options
context:
space:
mode:
Diffstat (limited to 'django/core/serializers/python.py')
-rw-r--r--django/core/serializers/python.py42
1 files changed, 32 insertions, 10 deletions
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
index 7b77804009..c6c2457258 100644
--- a/django/core/serializers/python.py
+++ b/django/core/serializers/python.py
@@ -47,17 +47,24 @@ class Serializer(base.Serializer):
def handle_fk_field(self, obj, field):
related = getattr(obj, field.name)
if related is not None:
- if field.rel.field_name == related._meta.pk.name:
- # Related to remote object via primary key
- related = related._get_pk_val()
+ if self.use_natural_keys and hasattr(related, 'natural_key'):
+ related = related.natural_key()
else:
- # Related to remote object via other field
- related = getattr(related, field.rel.field_name)
- self._current[field.name] = smart_unicode(related, strings_only=True)
+ if field.rel.field_name == related._meta.pk.name:
+ # Related to remote object via primary key
+ related = related._get_pk_val()
+ else:
+ # Related to remote object via other field
+ related = smart_unicode(getattr(related, field.rel.field_name), strings_only=True)
+ self._current[field.name] = related
def handle_m2m_field(self, obj, field):
if field.rel.through._meta.auto_created:
- self._current[field.name] = [smart_unicode(related._get_pk_val(), strings_only=True)
+ if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'):
+ m2m_value = lambda value: value.natural_key()
+ else:
+ m2m_value = lambda value: smart_unicode(value._get_pk_val(), strings_only=True)
+ self._current[field.name] = [m2m_value(related)
for related in getattr(obj, field.name).iterator()]
def getvalue(self):
@@ -86,13 +93,28 @@ def Deserializer(object_list, **options):
# Handle M2M relations
if field.rel and isinstance(field.rel, models.ManyToManyRel):
- m2m_convert = field.rel.to._meta.pk.to_python
- m2m_data[field.name] = [m2m_convert(smart_unicode(pk)) for pk in field_value]
+ if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
+ def m2m_convert(value):
+ if hasattr(value, '__iter__'):
+ return field.rel.to._default_manager.get_by_natural_key(*value).pk
+ else:
+ return smart_unicode(field.rel.to._meta.pk.to_python(value))
+ else:
+ m2m_convert = lambda v: smart_unicode(field.rel.to._meta.pk.to_python(v))
+ m2m_data[field.name] = [m2m_convert(pk) for pk in field_value]
# Handle FK fields
elif field.rel and isinstance(field.rel, models.ManyToOneRel):
if field_value is not None:
- data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
+ if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
+ if hasattr(field_value, '__iter__'):
+ obj = field.rel.to._default_manager.get_by_natural_key(*field_value)
+ value = getattr(obj, field.rel.field_name)
+ else:
+ value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
+ data[field.attname] = value
+ else:
+ data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
else:
data[field.attname] = None