Skip to content

Commit 58faebc

Browse files
committed
Merge pull request #3526 from likeon/fk-to_field
Added support for the to_field on ForeignKey fields
2 parents 825e674 + 322bda8 commit 58faebc

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

rest_framework/serializers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ class ModelSerializer(Serializer):
794794
if ModelJSONField is not None:
795795
serializer_field_mapping[ModelJSONField] = JSONField
796796
serializer_related_field = PrimaryKeyRelatedField
797+
serializer_related_to_field = SlugRelatedField
797798
serializer_url_field = HyperlinkedIdentityField
798799
serializer_choice_field = ChoiceField
799800

@@ -1129,6 +1130,11 @@ def build_relational_field(self, field_name, relation_info):
11291130
field_class = self.serializer_related_field
11301131
field_kwargs = get_relation_kwargs(field_name, relation_info)
11311132

1133+
to_field = field_kwargs.pop('to_field', None)
1134+
if to_field and to_field != 'id':
1135+
field_kwargs['slug_field'] = to_field
1136+
field_class = self.serializer_related_to_field
1137+
11321138
# `view_name` is only valid for hyperlinked relationships.
11331139
if not issubclass(field_class, HyperlinkedRelatedField):
11341140
field_kwargs.pop('view_name', None)

rest_framework/utils/field_mapping.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def get_relation_kwargs(field_name, relation_info):
222222
"""
223223
Creates a default instance of a flat relational field.
224224
"""
225-
model_field, related_model, to_many, has_through_model = relation_info
225+
model_field, related_model, to_many, to_field, has_through_model = relation_info
226226
kwargs = {
227227
'queryset': related_model._default_manager,
228228
'view_name': get_detail_view_name(related_model)
@@ -231,6 +231,9 @@ def get_relation_kwargs(field_name, relation_info):
231231
if to_many:
232232
kwargs['many'] = True
233233

234+
if to_field:
235+
kwargs['to_field'] = to_field
236+
234237
if has_through_model:
235238
kwargs['read_only'] = True
236239
kwargs.pop('queryset', None)

rest_framework/utils/model_meta.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
'model_field',
2727
'related_model',
2828
'to_many',
29+
'to_field',
2930
'has_through_model'
3031
])
3132

@@ -90,6 +91,10 @@ def _get_fields(opts):
9091
return fields
9192

9293

94+
def _get_to_field(field):
95+
return field.to_fields[0] if field.to_fields else None
96+
97+
9398
def _get_forward_relationships(opts):
9499
"""
95100
Returns an `OrderedDict` of field names to `RelationInfo`.
@@ -100,6 +105,7 @@ def _get_forward_relationships(opts):
100105
model_field=field,
101106
related_model=_resolve_model(field.rel.to),
102107
to_many=False,
108+
to_field=_get_to_field(field),
103109
has_through_model=False
104110
)
105111

@@ -109,6 +115,8 @@ def _get_forward_relationships(opts):
109115
model_field=field,
110116
related_model=_resolve_model(field.rel.to),
111117
to_many=True,
118+
# manytomany do not have to_fields
119+
to_field=None,
112120
has_through_model=(
113121
not field.rel.through._meta.auto_created
114122
)
@@ -133,6 +141,7 @@ def _get_reverse_relationships(opts):
133141
model_field=None,
134142
related_model=related,
135143
to_many=relation.field.rel.multiple,
144+
to_field=_get_to_field(relation.field),
136145
has_through_model=False
137146
)
138147

@@ -144,6 +153,8 @@ def _get_reverse_relationships(opts):
144153
model_field=None,
145154
related_model=related,
146155
to_many=True,
156+
# manytomany do not have to_fields
157+
to_field=None,
147158
has_through_model=(
148159
(getattr(relation.field.rel, 'through', None) is not None) and
149160
not relation.field.rel.through._meta.auto_created

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy