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
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() ])
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
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 ])
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 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)
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
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()