def _merge_fields_and_pk(pk, fields):
    fields_and_pk = OrderedDict()
    fields_and_pk['pk'] = pk
    fields_and_pk[pk.name] = pk
    fields_and_pk.update(fields)

    return fields_and_pk
def _get_reverse_relationships(opts):
    """
    Returns an `OrderedDict` of field names to `RelationInfo`.
    """
    # Note that we have a hack here to handle internal API differences for
    # this internal API across Django 1.7 -> Django 1.8.
    # See: https://code.djangoproject.com/ticket/24208

    reverse_relations = OrderedDict()
    for relation in opts.get_all_related_objects():
        accessor_name = relation.get_accessor_name()
        related = getattr(relation, 'related_model', relation.model)
        reverse_relations[accessor_name] = RelationInfo(
            model_field=None,
            related=related,
            to_many=relation.field.rel.multiple,
            has_through_model=False)

    # Deal with reverse many-to-many relationships.
    for relation in opts.get_all_related_many_to_many_objects():
        accessor_name = relation.get_accessor_name()
        related = getattr(relation, 'related_model', relation.model)
        reverse_relations[accessor_name] = RelationInfo(
            model_field=None,
            related=related,
            to_many=True,
            has_through_model=(
                (getattr(relation.field.rel, 'through', None) is not None)
                and not relation.field.rel.through._meta.auto_created))

    return reverse_relations
Esempio n. 3
0
    def get_api_root_view(self):
        """
        Return a view to use as the API root.
        """
        api_root_dict = OrderedDict()
        list_name = self.routes[0].name
        for prefix, viewset, basename in self.registry:
            api_root_dict[prefix] = list_name.format(basename=basename)

        class APIRoot(views.APIView):
            _ignore_model_permissions = True

            def get(self, request, *args, **kwargs):
                ret = OrderedDict()
                namespace = get_resolver_match(request).namespace
                for key, url_name in api_root_dict.items():
                    if namespace:
                        url_name = namespace + ':' + url_name
                    try:
                        ret[key] = reverse(url_name,
                                           request=request,
                                           format=kwargs.get('format', None))
                    except NoReverseMatch:
                        # Don't bail out if eg. no list routes exist, only detail routes.
                        continue

                return Response(ret)

        return APIRoot.as_view()
def _get_fields(opts):
    fields = OrderedDict()
    for field in [
            field for field in opts.fields if field.serialize and not field.rel
    ]:
        fields[field.name] = field

    return fields
 def choices(self):
     return OrderedDict([
         (
             six.text_type(self.to_representation(item)),
             six.text_type(item)
         )
         for item in self.queryset.all()
     ])
Esempio n. 6
0
 def determine_metadata(self, request, view):
     metadata = OrderedDict()
     metadata['name'] = view.get_view_name()
     metadata['description'] = view.get_view_description()
     metadata['renders'] = [renderer.media_type for renderer in view.renderer_classes]
     metadata['parses'] = [parser.media_type for parser in view.parser_classes]
     if hasattr(view, 'get_serializer'):
         actions = self.determine_actions(request, view)
         if actions:
             metadata['actions'] = actions
     return metadata
Esempio n. 7
0
 def get_serializer_info(self, serializer):
     """
     Given an instance of a serializer, return a dictionary of metadata
     about its fields.
     """
     if hasattr(serializer, 'child'):
         # If this is a `ListSerializer` then we want to examine the
         # underlying child serializer instance instead.
         serializer = serializer.child
     return OrderedDict([
         (field_name, self.get_field_info(field))
         for field_name, field in serializer.fields.items()
     ])
 def choices(self):
     queryset = self.child_relation.queryset
     iterable = queryset.all() if (hasattr(queryset, 'all')) else queryset
     items_and_representations = [
         (item, self.child_relation.to_representation(item))
         for item in iterable
     ]
     return OrderedDict([
         (
             six.text_type(item_representation),
             six.text_type(item) + ' - ' + six.text_type(item_representation)
         )
         for item, item_representation in items_and_representations
     ])
Esempio n. 9
0
    def __init__(self, choices, **kwargs):
        # Allow either single or paired choices style:
        # choices = [1, 2, 3]
        # choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
        pairs = [
            isinstance(item, (list, tuple)) and len(item) == 2
            for item in choices
        ]
        if all(pairs):
            self.choices = OrderedDict([(key, display_value)
                                        for key, display_value in choices])
        else:
            self.choices = OrderedDict([(item, item) for item in choices])

        # Map the string representation of choices to the underlying value.
        # Allows us to deal with eg. integer choices while supporting either
        # integer or string input, but still get the correct datatype out.
        self.choice_strings_to_values = dict([(six.text_type(key), key)
                                              for key in self.choices.keys()])

        self.allow_blank = kwargs.pop('allow_blank', False)

        super(ChoiceField, self).__init__(**kwargs)
Esempio n. 10
0
            def get(self, request, *args, **kwargs):
                ret = OrderedDict()
                namespace = get_resolver_match(request).namespace
                for key, url_name in api_root_dict.items():
                    if namespace:
                        url_name = namespace + ':' + url_name
                    try:
                        ret[key] = reverse(url_name,
                                           request=request,
                                           format=kwargs.get('format', None))
                    except NoReverseMatch:
                        # Don't bail out if eg. no list routes exist, only detail routes.
                        continue

                return Response(ret)
Esempio n. 11
0
class ChoiceField(Field):
    default_error_messages = {
        'invalid_choice': _('`{input}` is not a valid choice.')
    }

    def __init__(self, choices, **kwargs):
        # Allow either single or paired choices style:
        # choices = [1, 2, 3]
        # choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
        pairs = [
            isinstance(item, (list, tuple)) and len(item) == 2
            for item in choices
        ]
        if all(pairs):
            self.choices = OrderedDict([(key, display_value)
                                        for key, display_value in choices])
        else:
            self.choices = OrderedDict([(item, item) for item in choices])

        # Map the string representation of choices to the underlying value.
        # Allows us to deal with eg. integer choices while supporting either
        # integer or string input, but still get the correct datatype out.
        self.choice_strings_to_values = dict([(six.text_type(key), key)
                                              for key in self.choices.keys()])

        self.allow_blank = kwargs.pop('allow_blank', False)

        super(ChoiceField, self).__init__(**kwargs)

    def to_internal_value(self, data):
        if data == '' and self.allow_blank:
            return ''

        try:
            return self.choice_strings_to_values[six.text_type(data)]
        except KeyError:
            self.fail('invalid_choice', input=data)

    def to_representation(self, value):
        if value in ('', None):
            return value
        return self.choice_strings_to_values[six.text_type(value)]
def _get_forward_relationships(opts):
    """
    Returns an `OrderedDict` of field names to `RelationInfo`.
    """
    forward_relations = OrderedDict()
    for field in [
            field for field in opts.fields if field.serialize and field.rel
    ]:
        forward_relations[field.name] = RelationInfo(model_field=field,
                                                     related=_resolve_model(
                                                         field.rel.to),
                                                     to_many=False,
                                                     has_through_model=False)

    # Deal with forward many-to-many relationships.
    for field in [field for field in opts.many_to_many if field.serialize]:
        forward_relations[field.name] = RelationInfo(
            model_field=field,
            related=_resolve_model(field.rel.to),
            to_many=True,
            has_through_model=(not field.rel.through._meta.auto_created))

    return forward_relations
Esempio n. 13
0
    def get_field_info(self, field):
        """
        Given an instance of a serializer field, return a dictionary
        of metadata about it.
        """
        field_info = OrderedDict()
        field_info['type'] = self.label_lookup[field]
        field_info['required'] = getattr(field, 'required', False)

        for attr in ['read_only', 'label', 'help_text', 'min_length', 'max_length']:
            value = getattr(field, attr, None)
            if value is not None and value != '':
                field_info[attr] = force_text(value, strings_only=True)

        if hasattr(field, 'choices'):
            field_info['choices'] = [
                {
                    'value': choice_value,
                    'display_name': force_text(choice_name, strings_only=True)
                }
                for choice_value, choice_name in field.choices.items()
            ]

        return field_info
def _merge_relationships(forward_relations, reverse_relations):
    return OrderedDict(
        list(forward_relations.items()) + list(reverse_relations.items()))
 def __init__(self, serializer):
     self.serializer = serializer
     self.fields = OrderedDict()