From c38a93e4d9f5ab31b22616c5573bba67946be493 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Mon, 14 May 2007 14:14:49 +0000 Subject: [PATCH] Fixed #4288 -- Modified serializers to pay attention to the to_field attribute on ForeignKeys. Thanks to Sandro Dentella for the report and the helpful test case. git-svn-id: http://code.djangoproject.com/svn/django/trunk@5232 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/management.py | 19 +++++++++++-------- django/core/serializers/python.py | 7 +++++-- django/core/serializers/xml_serializer.py | 4 ++-- .../serializers_regress/models.py | 10 ++++++++++ .../serializers_regress/tests.py | 6 ++++++ 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/django/core/management.py b/django/core/management.py index 8785798abc..fda7050d5e 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -1404,20 +1404,23 @@ def load_data(fixture_labels, verbosity=1): if verbosity > 1: print "No %s fixture '%s' in %s." % \ (format, fixture_name, humanize(fixture_dir)) + + sequence_sql = backend.get_sql_sequence_reset(style, models) + if sequence_sql: + if verbosity > 1: + print "Resetting sequences" + for line in sequence_sql: + cursor.execute(line) + + transaction.commit() + transaction.leave_transaction_management() + if count[0] == 0: if verbosity > 0: print "No fixtures found." else: if verbosity > 0: print "Installed %d object(s) from %d fixture(s)" % tuple(count) - sequence_sql = backend.get_sql_sequence_reset(style, models) - if sequence_sql: - if verbosity > 1: - print "Resetting sequences" - for line in sequence_sql: - cursor.execute(line) - transaction.commit() - transaction.leave_transaction_management() load_data.help_doc = 'Installs the named fixture(s) in the database' load_data.args = "[--verbosity] fixture, fixture, ..." diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 29ce6bf9bd..66dbbff335 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -37,7 +37,7 @@ class Serializer(base.Serializer): def handle_fk_field(self, obj, field): related = getattr(obj, field.name) if related is not None: - related = related._get_pk_val() + related = getattr(related, field.rel.field_name) self._current[field.name] = related def handle_m2m_field(self, obj, field): @@ -80,7 +80,10 @@ def Deserializer(object_list, **options): # Handle FK fields elif field.rel and isinstance(field.rel, models.ManyToOneRel): - data[field.attname] = field.rel.to._meta.pk.to_python(field_value) + if field_value: + data[field.attname] = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value) + else: + data[field.attname] = None # Handle all other fields else: diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py index 3a0fdb5395..633001f5f0 100644 --- a/django/core/serializers/xml_serializer.py +++ b/django/core/serializers/xml_serializer.py @@ -82,7 +82,7 @@ class Serializer(base.Serializer): self._start_relational_field(field) related = getattr(obj, field.name) if related is not None: - self.xml.characters(str(related._get_pk_val())) + self.xml.characters(str(getattr(related, field.rel.field_name))) else: self.xml.addQuickElement("None") self.xml.endElement("field") @@ -181,7 +181,7 @@ class Deserializer(base.Deserializer): if len(node.childNodes) == 1 and node.childNodes[0].nodeName == 'None': return None else: - return field.rel.to._meta.pk.to_python( + return field.rel.to._meta.get_field(field.rel.field_name).to_python( getInnerText(node).strip().encode(self.encoding)) def _handle_m2m_field_node(self, node, field): diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py index c287b6e0d6..4e740b4b63 100644 --- a/tests/regressiontests/serializers_regress/models.py +++ b/tests/regressiontests/serializers_regress/models.py @@ -116,6 +116,16 @@ class FKSelfData(models.Model): class M2MSelfData(models.Model): data = models.ManyToManyField('self', null=True, symmetrical=False) + +class UniqueAnchor(models.Model): + """This is a model that can be used as + something for other models to point at""" + + data = models.CharField(unique=True, maxlength=30) + +class FKDataToField(models.Model): + data = models.ForeignKey(UniqueAnchor, null=True, to_field='data') + # The following test classes are for validating the # deserialization of objects that use a user-defined # field as the primary key. diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py index 97b3fbacbe..fdd464f1b4 100644 --- a/tests/regressiontests/serializers_regress/tests.py +++ b/tests/regressiontests/serializers_regress/tests.py @@ -184,6 +184,12 @@ The end."""), (m2m_obj, 445, M2MSelfData, []), (m2m_obj, 446, M2MSelfData, []), + (data_obj, 450, UniqueAnchor, "UAnchor 1"), + (fk_obj, 451, FKDataToField, "UAnchor 1"), + (fk_obj, 452, FKDataToField, "UAnchor 2"), + (fk_obj, 453, FKDataToField, None), + (data_obj, 454, UniqueAnchor, "UAnchor 2"), + (data_obj, 500, Anchor, "Anchor 3"), (data_obj, 501, Anchor, "Anchor 4"),