Fix a bug in options related to read-only RelatedField by jannon · Pull Request #2981 · encode/django-rest-framework (original) (raw)

This fixes #2811

Problem
The issue was discovered when an OPTIONS request to an endpoint blew up with the following error:

...
rest_framework/views.py:451: in dispatch
    response = self.handle_exception(exc)
rest_framework/views.py:448: in dispatch
    response = handler(request, *args, **kwargs)
rest_framework/views.py:462: in options
    data = self.metadata_class().determine_metadata(request, self)
rest_framework/metadata.py:64: in determine_metadata
    actions = self.determine_actions(request, view)
rest_framework/metadata.py:90: in determine_actions
    actions[method] = self.get_serializer_info(serializer)
rest_framework/metadata.py:107: in get_serializer_info
    for field_name, field in serializer.fields.items()
rest_framework/metadata.py:107: in <listcomp>
    for field_name, field in serializer.fields.items()
rest_framework/metadata.py:130: in get_field_info
    if hasattr(field, 'choices'):
rest_framework/relations.py:382: in choices
    for item in iterable

Tracing the problem, I found that iterable is None because the queryset from which it derives is None because the PrimaryKeyRelatedField from which it derives is read-only.

Solution
It is expected that the OPTIONS request should succeed and simply not list choices for read-only fields since, a user cannot submit data to them anyway.

This pull request contains both a test that fails on existing code and a fix in SimpleMetaData.get_field_info that checks if a field is read-only before attempting to get choices