from logging import getLogger from rest_framework import serializers, fields from rest_framework.metadata import SimpleMetadata from rest_framework.request import clone_request from django.utils.encoding import force_str log = getLogger(__name__) class ExpandedMetadata(SimpleMetadata): def determine_metadata(self, request, view): metadata = super().determine_metadata(request, view) if hasattr(view, "ordering_fields"): metadata["sort"] = view.ordering_fields if hasattr(view, "filterset_fields"): metadata["filter"] = view.filterset_fields return metadata def determine_actions(self, request, view): """ For generic class based views we return information about the fields that are accepted for 'PUT' and 'POST' methods. """ actions = {} for method in {'PUT', 'POST', "GET"} & set(view.allowed_methods): view.request = clone_request(request, method) try: # Test global permissions if hasattr(view, 'check_permissions'): view.check_permissions(view.request) # Test object permissions if method == 'PUT' and hasattr(view, 'get_object'): view.get_object() except (exceptions.APIException, PermissionDenied, Http404): pass else: # If user has appropriate permissions for the view, include # appropriate metadata about the fields that should be supplied. serializer = view.get_serializer() actions[method] = self.get_serializer_info(serializer) finally: view.request = request return actions def get_field_info(self, field): field_info = super().get_field_info(field) if hasattr(field, 'default') and field.default is not fields.empty: field_info['default'] = field.default if hasattr(field, 'initial') and field.initial is not fields.empty: field_info['initial'] = field.initial return field_info