示例#1
0
    def get_serializer_fields(self, path, method):
        """
        Return a list of `coreapi.Field` instances corresponding to any
        request body input, as determined by the serializer class.
        """

        view = self.view
        method_name = getattr(view, 'action', method.lower())
        parser_serializer = getattr(getattr(view, method_name),
                                    "_parser_serializer", None)

        if method not in ('PUT', 'PATCH', 'POST', 'DELETE'):
            return []

        if parser_serializer and isinstance(parser_serializer,
                                            serializers.Serializer):
            fields = []
            for field in parser_serializer.fields.values():
                if field.read_only or isinstance(field,
                                                 serializers.HiddenField):
                    continue
                required = field.required and method != 'PATCH'
                field = coreapi.Field(name=field.field_name,
                                      location='form',
                                      required=required,
                                      schema=field_to_schema(field))
                fields.append(field)
            return fields
        else:
            return super(CustomerSchema,
                         self).get_serializer_fields(path, method)
示例#2
0
    def get_response_object(self, response_serializer_class, description):

        fields = []
        serializer = response_serializer_class()
        nested_obj = {}

        for field in serializer.fields.values():
            # If field is a serializer, attempt to get its schema.
            if isinstance(field, serializers.Serializer):
                subfield_schema = self.get_response_object(
                    field.__class__, None)[0].get('schema')

                # If the schema exists, use it as the nested_obj
                if subfield_schema is not None:
                    nested_obj[field.field_name] = subfield_schema
                    nested_obj[
                        field.field_name]['description'] = field.help_text
                    continue

            # Otherwise, carry-on and use the field's schema.
            fallback_schema = self.fallback_schema_from_field(field)
            fields.append(
                Field(
                    name=field.field_name,
                    location='form',
                    required=field.required,
                    schema=fallback_schema
                    if fallback_schema else field_to_schema(field),
                ))

        res = _get_parameters(Link(fields=fields), None)

        if not res:
            if nested_obj:
                return {
                    'description': description,
                    'schema': {
                        'type': 'object',
                        'properties': nested_obj
                    }
                }, {}
            else:
                return {}, {}

        schema = res[0]['schema']
        schema['properties'].update(nested_obj)
        response_schema = {'description': description, 'schema': schema}

        error_status_codes = {}

        response_meta = getattr(response_serializer_class, 'Meta', None)

        for status_code, description in getattr(response_meta,
                                                'error_status_codes',
                                                {}).items():
            error_status_codes[status_code] = {'description': description}

        return response_schema, error_status_codes
示例#3
0
    def get_serializer_fields(self,
                              path,
                              method,
                              view,
                              version=None,
                              method_func=None):
        """
        Return a list of `coreapi.Field` instances corresponding to any
        request body input, as determined by the serializer class.
        """
        if method in ('PUT', 'PATCH', 'POST'):
            location = 'form'
        else:
            location = 'query'

        serializer_class = self.get_serializer_class(view, method_func)
        if not serializer_class:
            return []

        serializer = serializer_class()
        if isinstance(serializer, serializers.ListSerializer):
            return [
                Field(name='data',
                      location=location,
                      required=True,
                      schema=coreschema.Array())
            ]

        if not isinstance(serializer, serializers.Serializer):
            return []

        fields = []
        for field in serializer.fields.values():
            if field.read_only or isinstance(field, serializers.HiddenField):
                continue

            required = field.required and method != 'PATCH'
            # if the attribute ('help_text') of this field is a lazy translation object, force it to generate a string
            description = str(field.help_text) if isinstance(
                field.help_text, Promise) else field.help_text
            fallback_schema = self.fallback_schema_from_field(field)
            field = Field(
                name=field.field_name,
                location=location,
                required=required,
                schema=fallback_schema
                if fallback_schema else field_to_schema(field),
                description=description,
            )
            fields.append(field)

        return fields
    def add_object_definitions(self, method, view):
        """Create an Object definition from serializer
        It will create a different definitions depending on the method, definition name is
        {serializer class name}_{read|write}
        POST, PUT, PATCH is write
        GET, DELETE, HEAD is read
        write methods will not include read only fields
        read methods will not include write only fields
        Note that for write methods it will also return a read definition because by default this is the definition
        object returned by write methods
        :param str method: GET, POST etc
        :param rest_framework.generics.GenericAPIView view:
        """
        if not hasattr(view, 'get_serializer'):
            return None
        try:
            serializer = view.get_serializer()
        except AssertionError:  # Default behaviour of GenericAPIView is to raise AssertionError
            return None
        if method in ('POST', 'PUT', 'PATCH'):
            write = True
            # also generate a read definition, because it is commonly used as response for write actions
            self.add_object_definitions('GET', view)
            name = '%s_write' % serializer.__class__.__name__
        elif method in ('GET', 'DELETE', 'HEAD'):
            write = False
            name = '%s_read' % serializer.__class__.__name__
        else:
            assert False, 'Can not recognize method %s' % method
        if name in self.definitions:
            return
        fields = []
        for field in serializer.fields.values():
            if isinstance(field, serializers.HiddenField) or write and field.read_only or \
                            not write and field.write_only:
                continue

            # required = bool(field.required)  # field.required is a list
            field = field_to_schema(field)
            fields.append(field)

        self.definitions[name] = coreschema.Object(title=name,
                                                   properties=fields)
        return self.definitions[name]
    def test_field_to_schema(self):
        label = 'Test label'
        help_text = 'This is a helpful test text'

        cases = [
            # tuples are ([field], [expected schema])
            # TODO: Add remaining cases
            (
                serializers.BooleanField(label=label, help_text=help_text),
                coreschema.Boolean(title=label, description=help_text)
            ),
            (
                serializers.DecimalField(1000, 1000, label=label, help_text=help_text),
                coreschema.Number(title=label, description=help_text)
            ),
            (
                serializers.FloatField(label=label, help_text=help_text),
                coreschema.Number(title=label, description=help_text)
            ),
            (
                serializers.IntegerField(label=label, help_text=help_text),
                coreschema.Integer(title=label, description=help_text)
            ),
            (
                serializers.DateField(label=label, help_text=help_text),
                coreschema.String(title=label, description=help_text, format='date')
            ),
            (
                serializers.DateTimeField(label=label, help_text=help_text),
                coreschema.String(title=label, description=help_text, format='date-time')
            ),
            (
                serializers.JSONField(label=label, help_text=help_text),
                coreschema.Object(title=label, description=help_text)
            ),
        ]

        for case in cases:
            self.assertEqual(field_to_schema(case[0]), case[1])