From 8a58b1a380cb3544d904524e0f040dca44f972de Mon Sep 17 00:00:00 2001 From: Devon Bleibtrey Date: Sun, 22 Mar 2015 13:50:05 -0400 Subject: [PATCH 1/3] Added ability to define backend identification attribute --- rest_framework/relations.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 3a966c5bf..13668975c 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -166,6 +166,7 @@ class HyperlinkedRelatedField(RelatedField): self.lookup_field = kwargs.pop('lookup_field', self.lookup_field) self.lookup_url_kwarg = kwargs.pop('lookup_url_kwarg', self.lookup_field) self.format = kwargs.pop('format', None) + self.id_field = kwargs.pop('id_field', 'pk') # We include this simply for dependency injection in tests. # We can't add it as a class attributes or it would expect an @@ -196,7 +197,7 @@ class HyperlinkedRelatedField(RelatedField): attributes are not configured to correctly match the URL conf. """ # Unsaved objects will not yet have a valid URL. - if obj.pk is None: + if getattr(obj, self.id_field) is None: return None lookup_value = getattr(obj, self.lookup_field) From 7ac3c3fff7ae029a331ae0b6c149ac5ab97357fc Mon Sep 17 00:00:00 2001 From: Devon Bleibtrey Date: Mon, 23 Mar 2015 10:42:42 -0400 Subject: [PATCH 2/3] Added enhancement for pk reference in many=True relations --- rest_framework/relations.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 13668975c..7483a9390 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -341,6 +341,7 @@ class ManyRelatedField(Field): assert child_relation is not None, '`child_relation` is a required argument.' super(ManyRelatedField, self).__init__(*args, **kwargs) self.child_relation.bind(field_name='', parent=self) + self.id_field = kwargs.pop('id_field', 'pk') def get_value(self, dictionary): # We override the default field access in order to support @@ -362,7 +363,7 @@ class ManyRelatedField(Field): def get_attribute(self, instance): # Can't have any relationships if not created - if not instance.pk: + if getattr(instance, self.id_field) is None: return [] relationship = get_attribute(instance, self.source_attrs) From b1c1867b162c8eb9b7c2807029397d27a01ce19c Mon Sep 17 00:00:00 2001 From: Devon Bleibtrey Date: Mon, 23 Mar 2015 11:40:33 -0400 Subject: [PATCH 3/3] Swapping to hassattr logic for pk attribute references in relations --- rest_framework/relations.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 7483a9390..00a4a2656 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -166,7 +166,6 @@ class HyperlinkedRelatedField(RelatedField): self.lookup_field = kwargs.pop('lookup_field', self.lookup_field) self.lookup_url_kwarg = kwargs.pop('lookup_url_kwarg', self.lookup_field) self.format = kwargs.pop('format', None) - self.id_field = kwargs.pop('id_field', 'pk') # We include this simply for dependency injection in tests. # We can't add it as a class attributes or it would expect an @@ -197,7 +196,7 @@ class HyperlinkedRelatedField(RelatedField): attributes are not configured to correctly match the URL conf. """ # Unsaved objects will not yet have a valid URL. - if getattr(obj, self.id_field) is None: + if hasattr(obj, 'pk') and obj.pk is None: return None lookup_value = getattr(obj, self.lookup_field) @@ -341,7 +340,6 @@ class ManyRelatedField(Field): assert child_relation is not None, '`child_relation` is a required argument.' super(ManyRelatedField, self).__init__(*args, **kwargs) self.child_relation.bind(field_name='', parent=self) - self.id_field = kwargs.pop('id_field', 'pk') def get_value(self, dictionary): # We override the default field access in order to support @@ -363,7 +361,7 @@ class ManyRelatedField(Field): def get_attribute(self, instance): # Can't have any relationships if not created - if getattr(instance, self.id_field) is None: + if hasattr(instance, 'pk') and instance.pk is None: return [] relationship = get_attribute(instance, self.source_attrs)