Example #1
0
    def __get_serializer_fields__(self, callback):
        """
        Gets serializer fields if set in the view. Returns dictionaries
        with field properties (read-only, default, min and max length)
        """
        data = []
        if not hasattr(callback, 'get_serializer_class'):
            return data

        factory = RequestFactory()
        request = factory.get('')
        request.user = get_user_model()()

        if hasattr(callback, '__call__'):
            callback = callback()

        callback.request = request
        serializer = callback.get_serializer_class()

        try:
            fields = serializer().get_fields()
        except:
            return

        for name, field in fields.items():
            field_data = {}
            field_data['type'] = self.__camelcase_to_spaces(field.__class__.__name__)

            for key in ('read_only', 'default', 'max_length', 'min_length'):
                if hasattr(field, key):
                    field_data[key] = getattr(field, key)

            data.append({name: field_data})

        return data
Example #2
0
 def _get_flagged_field_names(self, fields, attr, meta_attr=None):
     if meta_attr is None:
         meta_attr = '%s_fields' % attr
     meta_list = set(getattr(self.Meta, meta_attr, []))
     return {
         name
         for name, field in iter(fields.items())
         if getattr(field, attr, None) is True or name in meta_list
     }
Example #3
0
    def get_field(self, field_name):
        # it might be deferred
        fields = self.get_all_fields()
        if field_name == 'pk':
            meta = self.get_meta()
            if hasattr(meta, '_pk'):
                return meta._pk

            field = None
            model = self.get_model()
            primary_key = getattr(meta, 'primary_key', None)

            if primary_key:
                field = fields.get(primary_key)
            else:
                for n, f in fields.items():
                    # try to use model fields
                    try:
                        if getattr(field, 'primary_key', False):
                            field = f
                            break

                        model_field = get_model_field(model, f.source or n)

                        if model_field.primary_key:
                            field = f
                            break
                    except:
                        pass

            if not field:
                # fall back to a field called ID
                if 'id' in fields:
                    field = fields['id']

            if field:
                meta._pk = field
                return field
        else:
            if field_name in fields:
                field = fields[field_name]
                return field

        raise ValidationError(
            {field_name: '"%s" is not an API field' % field_name})
Example #4
0
    def __get_serializer_fields__(self, callback):
        """
        Gets serializer fields if set in the view. Returns dictionaries
        with field properties (read-only, default, min and max length)
        """
        data = []
        if not hasattr(callback, 'get_serializer_class'):
            return data

        factory = RequestFactory()
        request = factory.get('')
        request.user = get_user_model()()

        if hasattr(callback, '__call__'):
            callback = callback()

        callback.request = request
        serializer = callback.get_serializer_class()

        try:
            fields = serializer().get_fields()
        except:
            return

        for name, field in fields.items():
            field_data = {}
            field_data['type'] = self.__camelcase_to_spaces(
                field.__class__.__name__)

            for key in ('read_only', 'default', 'max_length', 'min_length'):
                if hasattr(field, key):
                    field_data[key] = getattr(field, key)

            data.append({name: field_data})

        return data
def extract_serializer_fields(serializer, write=False):
    if serializer is None:
        return []

    if hasattr(serializer, '__call__'):
        fields = serializer().get_fields()
    else:
        fields = serializer.get_fields()

    serializer_data = []
    for name, field in fields.items():
        data_type, data_format = get_data_type(field) or ('string', 'string')

        if data_type == 'hidden':
            continue

        data_format = get_normalized_data_format(data_type, data_format)

        field_data = {
            'minimum': None,
            'maximum': None,
            'enum': None,
            'items': None,
            '$ref': None,
            'name': name,
            'type': data_type,
            'format': data_format,
            'write_only': getattr(field, 'write_only', False),
            'read_only': getattr(field, 'read_only', False),
            'required': getattr(field, 'required', False),
            'default': get_default_value(field),
        }

        help_text = getattr(field, 'help_text', '')
        field_data['description'] = help_text.strip() if help_text else ''

        # guess format
        # data_format = 'string'
        # if data_type in BaseMethodIntrospector.PRIMITIVES:
        # data_format = BaseMethodIntrospector.PRIMITIVES.get(data_type)[0]


        # Min/Max values
        max_value = getattr(field, 'max_value', None)
        min_value = getattr(field, 'min_value', None)

        if data_type == 'integer':
            field_data['minimum'] = min_value
            field_data['maximum'] = max_value

        # ENUM options
        if data_type in BaseMethodIntrospector.ENUMS:
            if isinstance(field.choices, list):
                field_data['enum'] = [k for k, v in field.choices]
            elif isinstance(field.choices, dict):
                field_data['enum'] = [k for k, v in field.choices.items()]

        # Support for complex types
        if rest_framework.VERSION < '3.0.0':
            has_many = hasattr(field, 'many') and field.many
        else:
            from rest_framework.serializers import ListSerializer, ManyRelatedField
            has_many = isinstance(field, (ListSerializer, ManyRelatedField))

        if isinstance(field, rest_framework.serializers.BaseSerializer) or has_many:
            field_serializer = None
            if hasattr(field, 'is_documented') and not field.is_documented:
                field_data['type'] = 'object'
            elif isinstance(field, rest_framework.serializers.BaseSerializer):
                field_serializer = get_serializer_name(field, write)
                if getattr(field, 'write_only', False):
                    field_serializer = "Write{}".format(field_serializer)
                if not has_many:
                    field_data['$ref'] = '#/definitions/' + field_serializer
            else:
                data_type = 'string'

            if has_many:
                field_data['type'] = 'array'
                if field_serializer:
                    field_data['items'] = {'$ref': '#/definitions/' + field_serializer}
                elif data_type in BaseMethodIntrospector.PRIMITIVES:
                    field_data['items'] = {'type': data_type}

        elif isinstance(field, rest_framework.serializers.ListField):
            field_data['type'] = 'array'
            if not field.child:
                field_data['items'] = {'type': 'string'}
            child_type, child_format = get_data_type(field.child) or ('string', 'string')
            field_data['items'] = {'type': child_type}

        serializer_data.append(field_data)
    return serializer_data