mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-27 17:54:08 +03:00
Merge pull request #3526 from likeon/fk-to_field
Added support for the to_field on ForeignKey fields
This commit is contained in:
commit
58faebcdb1
|
@ -794,6 +794,7 @@ class ModelSerializer(Serializer):
|
||||||
if ModelJSONField is not None:
|
if ModelJSONField is not None:
|
||||||
serializer_field_mapping[ModelJSONField] = JSONField
|
serializer_field_mapping[ModelJSONField] = JSONField
|
||||||
serializer_related_field = PrimaryKeyRelatedField
|
serializer_related_field = PrimaryKeyRelatedField
|
||||||
|
serializer_related_to_field = SlugRelatedField
|
||||||
serializer_url_field = HyperlinkedIdentityField
|
serializer_url_field = HyperlinkedIdentityField
|
||||||
serializer_choice_field = ChoiceField
|
serializer_choice_field = ChoiceField
|
||||||
|
|
||||||
|
@ -1129,6 +1130,11 @@ class ModelSerializer(Serializer):
|
||||||
field_class = self.serializer_related_field
|
field_class = self.serializer_related_field
|
||||||
field_kwargs = get_relation_kwargs(field_name, relation_info)
|
field_kwargs = get_relation_kwargs(field_name, relation_info)
|
||||||
|
|
||||||
|
to_field = field_kwargs.pop('to_field', None)
|
||||||
|
if to_field and to_field != 'id':
|
||||||
|
field_kwargs['slug_field'] = to_field
|
||||||
|
field_class = self.serializer_related_to_field
|
||||||
|
|
||||||
# `view_name` is only valid for hyperlinked relationships.
|
# `view_name` is only valid for hyperlinked relationships.
|
||||||
if not issubclass(field_class, HyperlinkedRelatedField):
|
if not issubclass(field_class, HyperlinkedRelatedField):
|
||||||
field_kwargs.pop('view_name', None)
|
field_kwargs.pop('view_name', None)
|
||||||
|
|
|
@ -222,7 +222,7 @@ def get_relation_kwargs(field_name, relation_info):
|
||||||
"""
|
"""
|
||||||
Creates a default instance of a flat relational field.
|
Creates a default instance of a flat relational field.
|
||||||
"""
|
"""
|
||||||
model_field, related_model, to_many, has_through_model = relation_info
|
model_field, related_model, to_many, to_field, has_through_model = relation_info
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'queryset': related_model._default_manager,
|
'queryset': related_model._default_manager,
|
||||||
'view_name': get_detail_view_name(related_model)
|
'view_name': get_detail_view_name(related_model)
|
||||||
|
@ -231,6 +231,9 @@ def get_relation_kwargs(field_name, relation_info):
|
||||||
if to_many:
|
if to_many:
|
||||||
kwargs['many'] = True
|
kwargs['many'] = True
|
||||||
|
|
||||||
|
if to_field:
|
||||||
|
kwargs['to_field'] = to_field
|
||||||
|
|
||||||
if has_through_model:
|
if has_through_model:
|
||||||
kwargs['read_only'] = True
|
kwargs['read_only'] = True
|
||||||
kwargs.pop('queryset', None)
|
kwargs.pop('queryset', None)
|
||||||
|
|
|
@ -26,6 +26,7 @@ RelationInfo = namedtuple('RelationInfo', [
|
||||||
'model_field',
|
'model_field',
|
||||||
'related_model',
|
'related_model',
|
||||||
'to_many',
|
'to_many',
|
||||||
|
'to_field',
|
||||||
'has_through_model'
|
'has_through_model'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -90,6 +91,10 @@ def _get_fields(opts):
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
|
def _get_to_field(field):
|
||||||
|
return field.to_fields[0] if field.to_fields else None
|
||||||
|
|
||||||
|
|
||||||
def _get_forward_relationships(opts):
|
def _get_forward_relationships(opts):
|
||||||
"""
|
"""
|
||||||
Returns an `OrderedDict` of field names to `RelationInfo`.
|
Returns an `OrderedDict` of field names to `RelationInfo`.
|
||||||
|
@ -100,6 +105,7 @@ def _get_forward_relationships(opts):
|
||||||
model_field=field,
|
model_field=field,
|
||||||
related_model=_resolve_model(field.rel.to),
|
related_model=_resolve_model(field.rel.to),
|
||||||
to_many=False,
|
to_many=False,
|
||||||
|
to_field=_get_to_field(field),
|
||||||
has_through_model=False
|
has_through_model=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -109,6 +115,8 @@ def _get_forward_relationships(opts):
|
||||||
model_field=field,
|
model_field=field,
|
||||||
related_model=_resolve_model(field.rel.to),
|
related_model=_resolve_model(field.rel.to),
|
||||||
to_many=True,
|
to_many=True,
|
||||||
|
# manytomany do not have to_fields
|
||||||
|
to_field=None,
|
||||||
has_through_model=(
|
has_through_model=(
|
||||||
not field.rel.through._meta.auto_created
|
not field.rel.through._meta.auto_created
|
||||||
)
|
)
|
||||||
|
@ -133,6 +141,7 @@ def _get_reverse_relationships(opts):
|
||||||
model_field=None,
|
model_field=None,
|
||||||
related_model=related,
|
related_model=related,
|
||||||
to_many=relation.field.rel.multiple,
|
to_many=relation.field.rel.multiple,
|
||||||
|
to_field=_get_to_field(relation.field),
|
||||||
has_through_model=False
|
has_through_model=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -144,6 +153,8 @@ def _get_reverse_relationships(opts):
|
||||||
model_field=None,
|
model_field=None,
|
||||||
related_model=related,
|
related_model=related,
|
||||||
to_many=True,
|
to_many=True,
|
||||||
|
# manytomany do not have to_fields
|
||||||
|
to_field=None,
|
||||||
has_through_model=(
|
has_through_model=(
|
||||||
(getattr(relation.field.rel, 'through', None) is not None) and
|
(getattr(relation.field.rel, 'through', None) is not None) and
|
||||||
not relation.field.rel.through._meta.auto_created
|
not relation.field.rel.through._meta.auto_created
|
||||||
|
|
Loading…
Reference in New Issue
Block a user