diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2009-12-14 12:39:20 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2009-12-14 12:39:20 +0000 |
| commit | 35cc439228cd32dfa7a3ec919db01a8a5cd17d33 (patch) | |
| tree | ed9aff433487895c0e649994450fd0accb6362d2 /django/core/serializers/python.py | |
| parent | 44b9076bbed3e629230d9b77a8765e4c906036d1 (diff) | |
Fixed #7052 -- Added support for natural keys in serialization.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11863 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/core/serializers/python.py')
| -rw-r--r-- | django/core/serializers/python.py | 42 |
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 |
