mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-06 13:30:12 +03:00
Added support for the to_field on ForeignKey Fields.
Uses the SlugRelatedField instead. SlugRelatedField will only get the Slugfield from the ORM as it does not need the other stuff
This commit is contained in:
parent
4f27b966a5
commit
067360c4ee
|
@ -303,7 +303,7 @@ class SlugRelatedField(RelatedField):
|
||||||
|
|
||||||
def to_internal_value(self, data):
|
def to_internal_value(self, data):
|
||||||
try:
|
try:
|
||||||
return self.get_queryset().get(**{self.slug_field: data})
|
return self.get_queryset().only(self.slug_field).get(**{self.slug_field: data})
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
self.fail('does_not_exist', slug_name=self.slug_field, value=smart_text(data))
|
self.fail('does_not_exist', slug_name=self.slug_field, value=smart_text(data))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
|
|
|
@ -727,6 +727,7 @@ class ModelSerializer(Serializer):
|
||||||
models.URLField: URLField,
|
models.URLField: URLField,
|
||||||
})
|
})
|
||||||
_related_class = PrimaryKeyRelatedField
|
_related_class = PrimaryKeyRelatedField
|
||||||
|
_related_to_field_class = SlugRelatedField
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
"""
|
"""
|
||||||
|
@ -1002,8 +1003,15 @@ class ModelSerializer(Serializer):
|
||||||
field_cls = self._get_nested_class(depth, relation_info)
|
field_cls = self._get_nested_class(depth, relation_info)
|
||||||
kwargs = get_nested_relation_kwargs(relation_info)
|
kwargs = get_nested_relation_kwargs(relation_info)
|
||||||
else:
|
else:
|
||||||
field_cls = self._related_class
|
|
||||||
kwargs = get_relation_kwargs(field_name, relation_info)
|
kwargs = get_relation_kwargs(field_name, relation_info)
|
||||||
|
to_field = kwargs.get('to_field', False)
|
||||||
|
if to_field:
|
||||||
|
# using the slug field for now
|
||||||
|
kwargs.pop('to_field', None)
|
||||||
|
kwargs['slug_field'] = to_field
|
||||||
|
field_cls = self._related_to_field_class
|
||||||
|
else:
|
||||||
|
field_cls = self._related_class
|
||||||
# `view_name` is only valid for hyperlinked relationships.
|
# `view_name` is only valid for hyperlinked relationships.
|
||||||
if not issubclass(field_cls, HyperlinkedRelatedField):
|
if not issubclass(field_cls, HyperlinkedRelatedField):
|
||||||
kwargs.pop('view_name', None)
|
kwargs.pop('view_name', None)
|
||||||
|
|
|
@ -194,7 +194,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)
|
||||||
|
@ -203,6 +203,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',
|
'related',
|
||||||
'to_many',
|
'to_many',
|
||||||
|
'to_field',
|
||||||
'has_through_model'
|
'has_through_model'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -96,10 +97,13 @@ def _get_forward_relationships(opts):
|
||||||
"""
|
"""
|
||||||
forward_relations = OrderedDict()
|
forward_relations = OrderedDict()
|
||||||
for field in [field for field in opts.fields if field.serialize and field.rel]:
|
for field in [field for field in opts.fields if field.serialize and field.rel]:
|
||||||
|
|
||||||
forward_relations[field.name] = RelationInfo(
|
forward_relations[field.name] = RelationInfo(
|
||||||
model_field=field,
|
model_field=field,
|
||||||
related=_resolve_model(field.rel.to),
|
related=_resolve_model(field.rel.to),
|
||||||
to_many=False,
|
to_many=False,
|
||||||
|
# to_fields is an array but django lets you only set one to_field
|
||||||
|
to_field=field.to_fields[0] if len(field.to_fields) else None,
|
||||||
has_through_model=False
|
has_through_model=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -109,6 +113,8 @@ def _get_forward_relationships(opts):
|
||||||
model_field=field,
|
model_field=field,
|
||||||
related=_resolve_model(field.rel.to),
|
related=_resolve_model(field.rel.to),
|
||||||
to_many=True,
|
to_many=True,
|
||||||
|
# to_fields is an array but django lets you only set one to_field
|
||||||
|
to_field=field.to_fields[0] if len(field.to_fields) else None,
|
||||||
has_through_model=(
|
has_through_model=(
|
||||||
not field.rel.through._meta.auto_created
|
not field.rel.through._meta.auto_created
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user