diff options
author | Peter Inglesby <peter.inglesby@gmail.com> | 2018-07-13 22:54:47 +0100 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2018-07-13 17:54:47 -0400 |
commit | 312eb5cb11d09c0c41b2740e2e9aef838d60c8b5 (patch) | |
tree | 00dec6ddb620204930bc2c870e1bb73c5bb87973 /django/core/serializers/python.py | |
parent | 8f75d21a2e6d255848ae441d858c6ea819e3d100 (diff) | |
download | django-312eb5cb11d09c0c41b2740e2e9aef838d60c8b5.tar.gz |
Fixed #26291 -- Allowed loaddata to handle forward references in natural_key fixtures.
Diffstat (limited to 'django/core/serializers/python.py')
-rw-r--r-- | django/core/serializers/python.py | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 922e2c6a8f..08739c98fc 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -83,6 +83,7 @@ def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False It's expected that you pass the Python objects themselves (instead of a stream or a string) to the constructor """ + handle_forward_references = options.pop('handle_forward_references', False) field_names_cache = {} # Model: <list of field_names> for d in object_list: @@ -101,6 +102,7 @@ def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), None) m2m_data = {} + deferred_fields = {} if Model not in field_names_cache: field_names_cache[Model] = {f.name for f in Model._meta.get_fields()} @@ -118,17 +120,23 @@ def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False # Handle M2M relations if field.remote_field and isinstance(field.remote_field, models.ManyToManyRel): try: - values = base.deserialize_m2m_values(field, field_value, using) + values = base.deserialize_m2m_values(field, field_value, using, handle_forward_references) except base.M2MDeserializationError as e: raise base.DeserializationError.WithData(e.original_exc, d['model'], d.get('pk'), e.pk) - m2m_data[field.name] = values + if values == base.DEFER_FIELD: + deferred_fields[field] = field_value + else: + m2m_data[field.name] = values # Handle FK fields elif field.remote_field and isinstance(field.remote_field, models.ManyToOneRel): try: - value = base.deserialize_fk_value(field, field_value, using) + value = base.deserialize_fk_value(field, field_value, using, handle_forward_references) except Exception as e: raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) - data[field.attname] = value + if value == base.DEFER_FIELD: + deferred_fields[field] = field_value + else: + data[field.attname] = value # Handle all other fields else: try: @@ -137,7 +145,7 @@ def Deserializer(object_list, *, using=DEFAULT_DB_ALIAS, ignorenonexistent=False raise base.DeserializationError.WithData(e, d['model'], d.get('pk'), field_value) obj = base.build_instance(Model, data, using) - yield base.DeserializedObject(obj, m2m_data) + yield base.DeserializedObject(obj, m2m_data, deferred_fields) def _get_model(model_identifier): |