mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-21 17:16:47 +03:00
Replaced OrderedDict
with dict
(#8964)
This commit is contained in:
parent
1ce0853ac5
commit
54307a4394
|
@ -6,7 +6,6 @@ import functools
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from collections import OrderedDict
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -143,7 +142,7 @@ def to_choices_dict(choices):
|
||||||
# choices = [1, 2, 3]
|
# choices = [1, 2, 3]
|
||||||
# choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
|
# choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
|
||||||
# choices = [('Category', ((1, 'First'), (2, 'Second'))), (3, 'Third')]
|
# choices = [('Category', ((1, 'First'), (2, 'Second'))), (3, 'Third')]
|
||||||
ret = OrderedDict()
|
ret = {}
|
||||||
for choice in choices:
|
for choice in choices:
|
||||||
if not isinstance(choice, (list, tuple)):
|
if not isinstance(choice, (list, tuple)):
|
||||||
# single choice
|
# single choice
|
||||||
|
@ -166,7 +165,7 @@ def flatten_choices_dict(choices):
|
||||||
flatten_choices_dict({1: '1st', 2: '2nd'}) -> {1: '1st', 2: '2nd'}
|
flatten_choices_dict({1: '1st', 2: '2nd'}) -> {1: '1st', 2: '2nd'}
|
||||||
flatten_choices_dict({'Group': {1: '1st', 2: '2nd'}}) -> {1: '1st', 2: '2nd'}
|
flatten_choices_dict({'Group': {1: '1st', 2: '2nd'}}) -> {1: '1st', 2: '2nd'}
|
||||||
"""
|
"""
|
||||||
ret = OrderedDict()
|
ret = {}
|
||||||
for key, value in choices.items():
|
for key, value in choices.items():
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
# grouped choices (category, sub choices)
|
# grouped choices (category, sub choices)
|
||||||
|
@ -1649,7 +1648,7 @@ class ListField(Field):
|
||||||
|
|
||||||
def run_child_validation(self, data):
|
def run_child_validation(self, data):
|
||||||
result = []
|
result = []
|
||||||
errors = OrderedDict()
|
errors = {}
|
||||||
|
|
||||||
for idx, item in enumerate(data):
|
for idx, item in enumerate(data):
|
||||||
try:
|
try:
|
||||||
|
@ -1713,7 +1712,7 @@ class DictField(Field):
|
||||||
|
|
||||||
def run_child_validation(self, data):
|
def run_child_validation(self, data):
|
||||||
result = {}
|
result = {}
|
||||||
errors = OrderedDict()
|
errors = {}
|
||||||
|
|
||||||
for key, value in data.items():
|
for key, value in data.items():
|
||||||
key = str(key)
|
key = str(key)
|
||||||
|
|
|
@ -6,8 +6,6 @@ some fairly ad-hoc information about the view.
|
||||||
Future implementations might use JSON schema or other definitions in order
|
Future implementations might use JSON schema or other definitions in order
|
||||||
to return this information in a more standardized way.
|
to return this information in a more standardized way.
|
||||||
"""
|
"""
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
@ -59,11 +57,12 @@ class SimpleMetadata(BaseMetadata):
|
||||||
})
|
})
|
||||||
|
|
||||||
def determine_metadata(self, request, view):
|
def determine_metadata(self, request, view):
|
||||||
metadata = OrderedDict()
|
metadata = {
|
||||||
metadata['name'] = view.get_view_name()
|
"name": view.get_view_name(),
|
||||||
metadata['description'] = view.get_view_description()
|
"description": view.get_view_description(),
|
||||||
metadata['renders'] = [renderer.media_type for renderer in view.renderer_classes]
|
"renders": [renderer.media_type for renderer in view.renderer_classes],
|
||||||
metadata['parses'] = [parser.media_type for parser in view.parser_classes]
|
"parses": [parser.media_type for parser in view.parser_classes],
|
||||||
|
}
|
||||||
if hasattr(view, 'get_serializer'):
|
if hasattr(view, 'get_serializer'):
|
||||||
actions = self.determine_actions(request, view)
|
actions = self.determine_actions(request, view)
|
||||||
if actions:
|
if actions:
|
||||||
|
@ -106,20 +105,21 @@ class SimpleMetadata(BaseMetadata):
|
||||||
# If this is a `ListSerializer` then we want to examine the
|
# If this is a `ListSerializer` then we want to examine the
|
||||||
# underlying child serializer instance instead.
|
# underlying child serializer instance instead.
|
||||||
serializer = serializer.child
|
serializer = serializer.child
|
||||||
return OrderedDict([
|
return {
|
||||||
(field_name, self.get_field_info(field))
|
field_name: self.get_field_info(field)
|
||||||
for field_name, field in serializer.fields.items()
|
for field_name, field in serializer.fields.items()
|
||||||
if not isinstance(field, serializers.HiddenField)
|
if not isinstance(field, serializers.HiddenField)
|
||||||
])
|
}
|
||||||
|
|
||||||
def get_field_info(self, field):
|
def get_field_info(self, field):
|
||||||
"""
|
"""
|
||||||
Given an instance of a serializer field, return a dictionary
|
Given an instance of a serializer field, return a dictionary
|
||||||
of metadata about it.
|
of metadata about it.
|
||||||
"""
|
"""
|
||||||
field_info = OrderedDict()
|
field_info = {
|
||||||
field_info['type'] = self.label_lookup[field]
|
"type": self.label_lookup[field],
|
||||||
field_info['required'] = getattr(field, 'required', False)
|
"required": getattr(field, "required", False),
|
||||||
|
}
|
||||||
|
|
||||||
attrs = [
|
attrs = [
|
||||||
'read_only', 'label', 'help_text',
|
'read_only', 'label', 'help_text',
|
||||||
|
|
|
@ -5,7 +5,7 @@ be used for paginated responses.
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from collections import OrderedDict, namedtuple
|
from collections import namedtuple
|
||||||
from urllib import parse
|
from urllib import parse
|
||||||
|
|
||||||
from django.core.paginator import InvalidPage
|
from django.core.paginator import InvalidPage
|
||||||
|
@ -225,12 +225,12 @@ class PageNumberPagination(BasePagination):
|
||||||
return page_number
|
return page_number
|
||||||
|
|
||||||
def get_paginated_response(self, data):
|
def get_paginated_response(self, data):
|
||||||
return Response(OrderedDict([
|
return Response({
|
||||||
('count', self.page.paginator.count),
|
'count': self.page.paginator.count,
|
||||||
('next', self.get_next_link()),
|
'next': self.get_next_link(),
|
||||||
('previous', self.get_previous_link()),
|
'previous': self.get_previous_link(),
|
||||||
('results', data)
|
'results': data,
|
||||||
]))
|
})
|
||||||
|
|
||||||
def get_paginated_response_schema(self, schema):
|
def get_paginated_response_schema(self, schema):
|
||||||
return {
|
return {
|
||||||
|
@ -395,12 +395,12 @@ class LimitOffsetPagination(BasePagination):
|
||||||
return list(queryset[self.offset:self.offset + self.limit])
|
return list(queryset[self.offset:self.offset + self.limit])
|
||||||
|
|
||||||
def get_paginated_response(self, data):
|
def get_paginated_response(self, data):
|
||||||
return Response(OrderedDict([
|
return Response({
|
||||||
('count', self.count),
|
'count': self.count,
|
||||||
('next', self.get_next_link()),
|
'next': self.get_next_link(),
|
||||||
('previous', self.get_previous_link()),
|
'previous': self.get_previous_link(),
|
||||||
('results', data)
|
'results': data
|
||||||
]))
|
})
|
||||||
|
|
||||||
def get_paginated_response_schema(self, schema):
|
def get_paginated_response_schema(self, schema):
|
||||||
return {
|
return {
|
||||||
|
@ -892,11 +892,11 @@ class CursorPagination(BasePagination):
|
||||||
return None if attr is None else str(attr)
|
return None if attr is None else str(attr)
|
||||||
|
|
||||||
def get_paginated_response(self, data):
|
def get_paginated_response(self, data):
|
||||||
return Response(OrderedDict([
|
return Response({
|
||||||
('next', self.get_next_link()),
|
'next': self.get_next_link(),
|
||||||
('previous', self.get_previous_link()),
|
'previous': self.get_previous_link(),
|
||||||
('results', data)
|
'results': data,
|
||||||
]))
|
})
|
||||||
|
|
||||||
def get_paginated_response_schema(self, schema):
|
def get_paginated_response_schema(self, schema):
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import sys
|
import sys
|
||||||
from collections import OrderedDict
|
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from urllib import parse
|
from urllib import parse
|
||||||
|
|
||||||
|
@ -199,13 +198,9 @@ class RelatedField(Field):
|
||||||
if cutoff is not None:
|
if cutoff is not None:
|
||||||
queryset = queryset[:cutoff]
|
queryset = queryset[:cutoff]
|
||||||
|
|
||||||
return OrderedDict([
|
return {
|
||||||
(
|
self.to_representation(item): self.display_value(item) for item in queryset
|
||||||
self.to_representation(item),
|
}
|
||||||
self.display_value(item)
|
|
||||||
)
|
|
||||||
for item in queryset
|
|
||||||
])
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def choices(self):
|
def choices(self):
|
||||||
|
|
|
@ -9,7 +9,6 @@ REST framework also provides an HTML renderer that renders the browsable API.
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import contextlib
|
import contextlib
|
||||||
from collections import OrderedDict
|
|
||||||
from urllib import parse
|
from urllib import parse
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
@ -653,7 +652,7 @@ class BrowsableAPIRenderer(BaseRenderer):
|
||||||
raw_data_patch_form = self.get_raw_data_form(data, view, 'PATCH', request)
|
raw_data_patch_form = self.get_raw_data_form(data, view, 'PATCH', request)
|
||||||
raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form
|
raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form
|
||||||
|
|
||||||
response_headers = OrderedDict(sorted(response.items()))
|
response_headers = dict(sorted(response.items()))
|
||||||
renderer_content_type = ''
|
renderer_content_type = ''
|
||||||
if renderer:
|
if renderer:
|
||||||
renderer_content_type = '%s' % renderer.media_type
|
renderer_content_type = '%s' % renderer.media_type
|
||||||
|
|
|
@ -14,7 +14,7 @@ For example, you might have a `urls.py` that looks something like this:
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
"""
|
"""
|
||||||
import itertools
|
import itertools
|
||||||
from collections import OrderedDict, namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.urls import NoReverseMatch, path, re_path
|
from django.urls import NoReverseMatch, path, re_path
|
||||||
|
@ -321,7 +321,7 @@ class APIRootView(views.APIView):
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# Return a plain {"name": "hyperlink"} response.
|
# Return a plain {"name": "hyperlink"} response.
|
||||||
ret = OrderedDict()
|
ret = {}
|
||||||
namespace = request.resolver_match.namespace
|
namespace = request.resolver_match.namespace
|
||||||
for key, url_name in self.api_root_dict.items():
|
for key, url_name in self.api_root_dict.items():
|
||||||
if namespace:
|
if namespace:
|
||||||
|
@ -365,7 +365,7 @@ class DefaultRouter(SimpleRouter):
|
||||||
"""
|
"""
|
||||||
Return a basic root view.
|
Return a basic root view.
|
||||||
"""
|
"""
|
||||||
api_root_dict = OrderedDict()
|
api_root_dict = {}
|
||||||
list_name = self.routes[0].name
|
list_name = self.routes[0].name
|
||||||
for prefix, viewset, basename in self.registry:
|
for prefix, viewset, basename in self.registry:
|
||||||
api_root_dict[prefix] = list_name.format(basename=basename)
|
api_root_dict[prefix] = list_name.format(basename=basename)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import warnings
|
import warnings
|
||||||
from collections import Counter, OrderedDict
|
from collections import Counter
|
||||||
from urllib import parse
|
from urllib import parse
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
@ -54,7 +54,7 @@ to customise schema structure.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class LinkNode(OrderedDict):
|
class LinkNode(dict):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.links = []
|
self.links = []
|
||||||
self.methods_counter = Counter()
|
self.methods_counter = Counter()
|
||||||
|
@ -268,11 +268,11 @@ def field_to_schema(field):
|
||||||
)
|
)
|
||||||
elif isinstance(field, serializers.Serializer):
|
elif isinstance(field, serializers.Serializer):
|
||||||
return coreschema.Object(
|
return coreschema.Object(
|
||||||
properties=OrderedDict([
|
properties={
|
||||||
(key, field_to_schema(value))
|
key: field_to_schema(value)
|
||||||
for key, value
|
for key, value
|
||||||
in field.fields.items()
|
in field.fields.items()
|
||||||
]),
|
},
|
||||||
title=title,
|
title=title,
|
||||||
description=description
|
description=description
|
||||||
)
|
)
|
||||||
|
@ -549,7 +549,7 @@ class AutoSchema(ViewInspector):
|
||||||
if not update_with:
|
if not update_with:
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
by_name = OrderedDict((f.name, f) for f in fields)
|
by_name = {f.name: f for f in fields}
|
||||||
for f in update_with:
|
for f in update_with:
|
||||||
by_name[f.name] = f
|
by_name[f.name] = f
|
||||||
fields = list(by_name.values())
|
fields = list(by_name.values())
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import re
|
import re
|
||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
|
@ -340,7 +339,7 @@ class AutoSchema(ViewInspector):
|
||||||
return paginator.get_schema_operation_parameters(view)
|
return paginator.get_schema_operation_parameters(view)
|
||||||
|
|
||||||
def map_choicefield(self, field):
|
def map_choicefield(self, field):
|
||||||
choices = list(OrderedDict.fromkeys(field.choices)) # preserve order and remove duplicates
|
choices = list(dict.fromkeys(field.choices)) # preserve order and remove duplicates
|
||||||
if all(isinstance(choice, bool) for choice in choices):
|
if all(isinstance(choice, bool) for choice in choices):
|
||||||
type = 'boolean'
|
type = 'boolean'
|
||||||
elif all(isinstance(choice, int) for choice in choices):
|
elif all(isinstance(choice, int) for choice in choices):
|
||||||
|
|
|
@ -15,7 +15,7 @@ import contextlib
|
||||||
import copy
|
import copy
|
||||||
import inspect
|
import inspect
|
||||||
import traceback
|
import traceback
|
||||||
from collections import OrderedDict, defaultdict
|
from collections import defaultdict
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
|
|
||||||
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
|
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
|
||||||
|
@ -308,7 +308,7 @@ class SerializerMetaclass(type):
|
||||||
for name, f in base._declared_fields.items() if name not in known
|
for name, f in base._declared_fields.items() if name not in known
|
||||||
]
|
]
|
||||||
|
|
||||||
return OrderedDict(base_fields + fields)
|
return dict(base_fields + fields)
|
||||||
|
|
||||||
def __new__(cls, name, bases, attrs):
|
def __new__(cls, name, bases, attrs):
|
||||||
attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
|
attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
|
||||||
|
@ -393,20 +393,20 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
|
||||||
if hasattr(self, 'initial_data'):
|
if hasattr(self, 'initial_data'):
|
||||||
# initial_data may not be a valid type
|
# initial_data may not be a valid type
|
||||||
if not isinstance(self.initial_data, Mapping):
|
if not isinstance(self.initial_data, Mapping):
|
||||||
return OrderedDict()
|
return {}
|
||||||
|
|
||||||
return OrderedDict([
|
return {
|
||||||
(field_name, field.get_value(self.initial_data))
|
field_name: field.get_value(self.initial_data)
|
||||||
for field_name, field in self.fields.items()
|
for field_name, field in self.fields.items()
|
||||||
if (field.get_value(self.initial_data) is not empty) and
|
if (field.get_value(self.initial_data) is not empty) and
|
||||||
not field.read_only
|
not field.read_only
|
||||||
])
|
}
|
||||||
|
|
||||||
return OrderedDict([
|
return {
|
||||||
(field.field_name, field.get_initial())
|
field.field_name: field.get_initial()
|
||||||
for field in self.fields.values()
|
for field in self.fields.values()
|
||||||
if not field.read_only
|
if not field.read_only
|
||||||
])
|
}
|
||||||
|
|
||||||
def get_value(self, dictionary):
|
def get_value(self, dictionary):
|
||||||
# We override the default field access in order to support
|
# We override the default field access in order to support
|
||||||
|
@ -441,7 +441,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
|
||||||
if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
|
if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
|
||||||
]
|
]
|
||||||
|
|
||||||
defaults = OrderedDict()
|
defaults = {}
|
||||||
for field in fields:
|
for field in fields:
|
||||||
try:
|
try:
|
||||||
default = field.get_default()
|
default = field.get_default()
|
||||||
|
@ -474,8 +474,8 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
|
||||||
api_settings.NON_FIELD_ERRORS_KEY: [message]
|
api_settings.NON_FIELD_ERRORS_KEY: [message]
|
||||||
}, code='invalid')
|
}, code='invalid')
|
||||||
|
|
||||||
ret = OrderedDict()
|
ret = {}
|
||||||
errors = OrderedDict()
|
errors = {}
|
||||||
fields = self._writable_fields
|
fields = self._writable_fields
|
||||||
|
|
||||||
for field in fields:
|
for field in fields:
|
||||||
|
@ -503,7 +503,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
|
||||||
"""
|
"""
|
||||||
Object instance -> Dict of primitive datatypes.
|
Object instance -> Dict of primitive datatypes.
|
||||||
"""
|
"""
|
||||||
ret = OrderedDict()
|
ret = {}
|
||||||
fields = self._readable_fields
|
fields = self._readable_fields
|
||||||
|
|
||||||
for field in fields:
|
for field in fields:
|
||||||
|
@ -1061,7 +1061,7 @@ class ModelSerializer(Serializer):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Determine the fields that should be included on the serializer.
|
# Determine the fields that should be included on the serializer.
|
||||||
fields = OrderedDict()
|
fields = {}
|
||||||
|
|
||||||
for field_name in field_names:
|
for field_name in field_names:
|
||||||
# If the field is explicitly declared on the class then use that.
|
# If the field is explicitly declared on the class then use that.
|
||||||
|
@ -1546,16 +1546,16 @@ class ModelSerializer(Serializer):
|
||||||
# which may map onto a model field. Any dotted field name lookups
|
# which may map onto a model field. Any dotted field name lookups
|
||||||
# cannot map to a field, and must be a traversal, so we're not
|
# cannot map to a field, and must be a traversal, so we're not
|
||||||
# including those.
|
# including those.
|
||||||
field_sources = OrderedDict(
|
field_sources = {
|
||||||
(field.field_name, field.source) for field in self._writable_fields
|
field.field_name: field.source for field in self._writable_fields
|
||||||
if (field.source != '*') and ('.' not in field.source)
|
if (field.source != '*') and ('.' not in field.source)
|
||||||
)
|
}
|
||||||
|
|
||||||
# Special Case: Add read_only fields with defaults.
|
# Special Case: Add read_only fields with defaults.
|
||||||
field_sources.update(OrderedDict(
|
field_sources.update({
|
||||||
(field.field_name, field.source) for field in self.fields.values()
|
field.field_name: field.source for field in self.fields.values()
|
||||||
if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
|
if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
|
||||||
))
|
})
|
||||||
|
|
||||||
# Invert so we can find the serializer field names that correspond to
|
# Invert so we can find the serializer field names that correspond to
|
||||||
# the model field names in the unique_together sets. This also allows
|
# the model field names in the unique_together sets. This also allows
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.template import loader
|
from django.template import loader
|
||||||
|
@ -49,10 +48,10 @@ def with_location(fields, location):
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def form_for_link(link):
|
def form_for_link(link):
|
||||||
import coreschema
|
import coreschema
|
||||||
properties = OrderedDict([
|
properties = {
|
||||||
(field.name, field.schema or coreschema.String())
|
field.name: field.schema or coreschema.String()
|
||||||
for field in link.fields
|
for field in link.fields
|
||||||
])
|
}
|
||||||
required = [
|
required = [
|
||||||
field.name
|
field.name
|
||||||
for field in link.fields
|
for field in link.fields
|
||||||
|
@ -272,7 +271,7 @@ def schema_links(section, sec_key=None):
|
||||||
links.update(new_links)
|
links.update(new_links)
|
||||||
|
|
||||||
if sec_key is not None:
|
if sec_key is not None:
|
||||||
new_links = OrderedDict()
|
new_links = {}
|
||||||
for link_key, link in links.items():
|
for link_key, link in links.items():
|
||||||
new_key = NESTED_FORMAT % (sec_key, link_key)
|
new_key = NESTED_FORMAT % (sec_key, link_key)
|
||||||
new_links.update({new_key: link})
|
new_links.update({new_key: link})
|
||||||
|
|
|
@ -5,7 +5,7 @@ relationships and their associated metadata.
|
||||||
|
|
||||||
Usage: `get_field_info(model)` returns a `FieldInfo` instance.
|
Usage: `get_field_info(model)` returns a `FieldInfo` instance.
|
||||||
"""
|
"""
|
||||||
from collections import OrderedDict, namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
FieldInfo = namedtuple('FieldResult', [
|
FieldInfo = namedtuple('FieldResult', [
|
||||||
'pk', # Model field instance
|
'pk', # Model field instance
|
||||||
|
@ -58,7 +58,7 @@ def _get_pk(opts):
|
||||||
|
|
||||||
|
|
||||||
def _get_fields(opts):
|
def _get_fields(opts):
|
||||||
fields = OrderedDict()
|
fields = {}
|
||||||
for field in [field for field in opts.fields if field.serialize and not field.remote_field]:
|
for field in [field for field in opts.fields if field.serialize and not field.remote_field]:
|
||||||
fields[field.name] = field
|
fields[field.name] = field
|
||||||
|
|
||||||
|
@ -71,9 +71,9 @@ def _get_to_field(field):
|
||||||
|
|
||||||
def _get_forward_relationships(opts):
|
def _get_forward_relationships(opts):
|
||||||
"""
|
"""
|
||||||
Returns an `OrderedDict` of field names to `RelationInfo`.
|
Returns a dict of field names to `RelationInfo`.
|
||||||
"""
|
"""
|
||||||
forward_relations = OrderedDict()
|
forward_relations = {}
|
||||||
for field in [field for field in opts.fields if field.serialize and field.remote_field]:
|
for field in [field for field in opts.fields if field.serialize and field.remote_field]:
|
||||||
forward_relations[field.name] = RelationInfo(
|
forward_relations[field.name] = RelationInfo(
|
||||||
model_field=field,
|
model_field=field,
|
||||||
|
@ -103,9 +103,9 @@ def _get_forward_relationships(opts):
|
||||||
|
|
||||||
def _get_reverse_relationships(opts):
|
def _get_reverse_relationships(opts):
|
||||||
"""
|
"""
|
||||||
Returns an `OrderedDict` of field names to `RelationInfo`.
|
Returns a dict of field names to `RelationInfo`.
|
||||||
"""
|
"""
|
||||||
reverse_relations = OrderedDict()
|
reverse_relations = {}
|
||||||
all_related_objects = [r for r in opts.related_objects if not r.field.many_to_many]
|
all_related_objects = [r for r in opts.related_objects if not r.field.many_to_many]
|
||||||
for relation in all_related_objects:
|
for relation in all_related_objects:
|
||||||
accessor_name = relation.get_accessor_name()
|
accessor_name = relation.get_accessor_name()
|
||||||
|
@ -139,19 +139,14 @@ def _get_reverse_relationships(opts):
|
||||||
|
|
||||||
|
|
||||||
def _merge_fields_and_pk(pk, fields):
|
def _merge_fields_and_pk(pk, fields):
|
||||||
fields_and_pk = OrderedDict()
|
fields_and_pk = {'pk': pk, pk.name: pk}
|
||||||
fields_and_pk['pk'] = pk
|
|
||||||
fields_and_pk[pk.name] = pk
|
|
||||||
fields_and_pk.update(fields)
|
fields_and_pk.update(fields)
|
||||||
|
|
||||||
return fields_and_pk
|
return fields_and_pk
|
||||||
|
|
||||||
|
|
||||||
def _merge_relationships(forward_relations, reverse_relations):
|
def _merge_relationships(forward_relations, reverse_relations):
|
||||||
return OrderedDict(
|
return {**forward_relations, **reverse_relations}
|
||||||
list(forward_relations.items()) +
|
|
||||||
list(reverse_relations.items())
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def is_abstract_model(model):
|
def is_abstract_model(model):
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import contextlib
|
import contextlib
|
||||||
import sys
|
import sys
|
||||||
from collections import OrderedDict
|
|
||||||
from collections.abc import Mapping, MutableMapping
|
from collections.abc import Mapping, MutableMapping
|
||||||
|
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
@ -8,7 +7,7 @@ from django.utils.encoding import force_str
|
||||||
from rest_framework.utils import json
|
from rest_framework.utils import json
|
||||||
|
|
||||||
|
|
||||||
class ReturnDict(OrderedDict):
|
class ReturnDict(dict):
|
||||||
"""
|
"""
|
||||||
Return object from `serializer.data` for the `Serializer` class.
|
Return object from `serializer.data` for the `Serializer` class.
|
||||||
Includes a backlink to the serializer instance for renderers
|
Includes a backlink to the serializer instance for renderers
|
||||||
|
@ -161,7 +160,7 @@ class BindingDict(MutableMapping):
|
||||||
|
|
||||||
def __init__(self, serializer):
|
def __init__(self, serializer):
|
||||||
self.serializer = serializer
|
self.serializer = serializer
|
||||||
self.fields = OrderedDict()
|
self.fields = {}
|
||||||
|
|
||||||
def __setitem__(self, key, field):
|
def __setitem__(self, key, field):
|
||||||
self.fields[key] = field
|
self.fields[key] = field
|
||||||
|
|
|
@ -16,7 +16,6 @@ automatically.
|
||||||
router.register(r'users', UserViewSet, 'user')
|
router.register(r'users', UserViewSet, 'user')
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
"""
|
"""
|
||||||
from collections import OrderedDict
|
|
||||||
from functools import update_wrapper
|
from functools import update_wrapper
|
||||||
from inspect import getmembers
|
from inspect import getmembers
|
||||||
|
|
||||||
|
@ -183,7 +182,7 @@ class ViewSetMixin:
|
||||||
|
|
||||||
This method will noop if `detail` was not provided as a view initkwarg.
|
This method will noop if `detail` was not provided as a view initkwarg.
|
||||||
"""
|
"""
|
||||||
action_urls = OrderedDict()
|
action_urls = {}
|
||||||
|
|
||||||
# exit early if `detail` has not been provided
|
# exit early if `detail` has not been provided
|
||||||
if self.detail is None:
|
if self.detail is None:
|
||||||
|
|
|
@ -10,7 +10,6 @@ import decimal
|
||||||
import json # noqa
|
import json # noqa
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
import django
|
import django
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -762,7 +761,7 @@ class TestRelationalFieldDisplayValue(TestCase):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
serializer = TestSerializer()
|
serializer = TestSerializer()
|
||||||
expected = OrderedDict([(1, 'Red Color'), (2, 'Yellow Color'), (3, 'Green Color')])
|
expected = {1: 'Red Color', 2: 'Yellow Color', 3: 'Green Color'}
|
||||||
self.assertEqual(serializer.fields['color'].choices, expected)
|
self.assertEqual(serializer.fields['color'].choices, expected)
|
||||||
|
|
||||||
def test_custom_display_value(self):
|
def test_custom_display_value(self):
|
||||||
|
@ -778,7 +777,7 @@ class TestRelationalFieldDisplayValue(TestCase):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
serializer = TestSerializer()
|
serializer = TestSerializer()
|
||||||
expected = OrderedDict([(1, 'My Red Color'), (2, 'My Yellow Color'), (3, 'My Green Color')])
|
expected = {1: 'My Red Color', 2: 'My Yellow Color', 3: 'My Green Color'}
|
||||||
self.assertEqual(serializer.fields['color'].choices, expected)
|
self.assertEqual(serializer.fields['color'].choices, expected)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import re
|
import re
|
||||||
from collections import OrderedDict
|
|
||||||
from collections.abc import MutableMapping
|
from collections.abc import MutableMapping
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -457,12 +456,12 @@ class CacheRenderTest(TestCase):
|
||||||
class TestJSONIndentationStyles:
|
class TestJSONIndentationStyles:
|
||||||
def test_indented(self):
|
def test_indented(self):
|
||||||
renderer = JSONRenderer()
|
renderer = JSONRenderer()
|
||||||
data = OrderedDict([('a', 1), ('b', 2)])
|
data = {"a": 1, "b": 2}
|
||||||
assert renderer.render(data) == b'{"a":1,"b":2}'
|
assert renderer.render(data) == b'{"a":1,"b":2}'
|
||||||
|
|
||||||
def test_compact(self):
|
def test_compact(self):
|
||||||
renderer = JSONRenderer()
|
renderer = JSONRenderer()
|
||||||
data = OrderedDict([('a', 1), ('b', 2)])
|
data = {"a": 1, "b": 2}
|
||||||
context = {'indent': 4}
|
context = {'indent': 4}
|
||||||
assert (
|
assert (
|
||||||
renderer.render(data, renderer_context=context) ==
|
renderer.render(data, renderer_context=context) ==
|
||||||
|
@ -472,7 +471,7 @@ class TestJSONIndentationStyles:
|
||||||
def test_long_form(self):
|
def test_long_form(self):
|
||||||
renderer = JSONRenderer()
|
renderer = JSONRenderer()
|
||||||
renderer.compact = False
|
renderer.compact = False
|
||||||
data = OrderedDict([('a', 1), ('b', 2)])
|
data = {"a": 1, "b": 2}
|
||||||
assert renderer.render(data) == b'{"a": 1, "b": 2}'
|
assert renderer.render(data) == b'{"a": 1, "b": 2}'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
from collections import OrderedDict
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -261,11 +260,11 @@ class GetExtraActionUrlMapTests(TestCase):
|
||||||
response = self.client.get('/api/actions/')
|
response = self.client.get('/api/actions/')
|
||||||
view = response.view
|
view = response.view
|
||||||
|
|
||||||
expected = OrderedDict([
|
expected = {
|
||||||
('Custom list action', 'http://testserver/api/actions/custom_list_action/'),
|
'Custom list action': 'http://testserver/api/actions/custom_list_action/',
|
||||||
('List action', 'http://testserver/api/actions/list_action/'),
|
'List action': 'http://testserver/api/actions/list_action/',
|
||||||
('Wrapped list action', 'http://testserver/api/actions/wrapped_list_action/'),
|
'Wrapped list action': 'http://testserver/api/actions/wrapped_list_action/',
|
||||||
])
|
}
|
||||||
|
|
||||||
self.assertEqual(view.get_extra_action_url_map(), expected)
|
self.assertEqual(view.get_extra_action_url_map(), expected)
|
||||||
|
|
||||||
|
@ -273,28 +272,28 @@ class GetExtraActionUrlMapTests(TestCase):
|
||||||
response = self.client.get('/api/actions/1/')
|
response = self.client.get('/api/actions/1/')
|
||||||
view = response.view
|
view = response.view
|
||||||
|
|
||||||
expected = OrderedDict([
|
expected = {
|
||||||
('Custom detail action', 'http://testserver/api/actions/1/custom_detail_action/'),
|
'Custom detail action': 'http://testserver/api/actions/1/custom_detail_action/',
|
||||||
('Detail action', 'http://testserver/api/actions/1/detail_action/'),
|
'Detail action': 'http://testserver/api/actions/1/detail_action/',
|
||||||
('Wrapped detail action', 'http://testserver/api/actions/1/wrapped_detail_action/'),
|
'Wrapped detail action': 'http://testserver/api/actions/1/wrapped_detail_action/',
|
||||||
# "Unresolvable detail action" excluded, since it's not resolvable
|
# "Unresolvable detail action" excluded, since it's not resolvable
|
||||||
])
|
}
|
||||||
|
|
||||||
self.assertEqual(view.get_extra_action_url_map(), expected)
|
self.assertEqual(view.get_extra_action_url_map(), expected)
|
||||||
|
|
||||||
def test_uninitialized_view(self):
|
def test_uninitialized_view(self):
|
||||||
self.assertEqual(ActionViewSet().get_extra_action_url_map(), OrderedDict())
|
self.assertEqual(ActionViewSet().get_extra_action_url_map(), {})
|
||||||
|
|
||||||
def test_action_names(self):
|
def test_action_names(self):
|
||||||
# Action 'name' and 'suffix' kwargs should be respected
|
# Action 'name' and 'suffix' kwargs should be respected
|
||||||
response = self.client.get('/api/names/1/')
|
response = self.client.get('/api/names/1/')
|
||||||
view = response.view
|
view = response.view
|
||||||
|
|
||||||
expected = OrderedDict([
|
expected = {
|
||||||
('Custom Name', 'http://testserver/api/names/1/named_action/'),
|
'Custom Name': 'http://testserver/api/names/1/named_action/',
|
||||||
('Action Names Custom Suffix', 'http://testserver/api/names/1/suffixed_action/'),
|
'Action Names Custom Suffix': 'http://testserver/api/names/1/suffixed_action/',
|
||||||
('Unnamed action', 'http://testserver/api/names/1/unnamed_action/'),
|
'Unnamed action': 'http://testserver/api/names/1/unnamed_action/',
|
||||||
])
|
}
|
||||||
|
|
||||||
self.assertEqual(view.get_extra_action_url_map(), expected)
|
self.assertEqual(view.get_extra_action_url_map(), expected)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user