change SortedDict to OrderedDict

This commit is contained in:
kazmiruk 2015-04-22 13:12:12 +07:00
parent 601b2241c9
commit 73978c9560
5 changed files with 28 additions and 27 deletions

View File

@ -22,7 +22,6 @@ from django.forms import widgets
from django.utils import six, timezone from django.utils import six, timezone
from django.utils.encoding import is_protected_type from django.utils.encoding import is_protected_type
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.datastructures import SortedDict
from django.utils.dateparse import parse_date, parse_datetime, parse_time from django.utils.dateparse import parse_date, parse_datetime, parse_time
from rest_framework import ISO_8601 from rest_framework import ISO_8601
from rest_framework.compat import ( from rest_framework.compat import (
@ -225,7 +224,7 @@ class Field(object):
return [self.to_native(item) for item in value] return [self.to_native(item) for item in value]
elif isinstance(value, dict): elif isinstance(value, dict):
# Make sure we preserve field ordering, if it exists # Make sure we preserve field ordering, if it exists
ret = SortedDict() ret = collections.OrderedDict()
for key, val in value.items(): for key, val in value.items():
ret[key] = self.to_native(val) ret[key] = self.to_native(val)
return ret return ret
@ -240,7 +239,7 @@ class Field(object):
return {} return {}
def metadata(self): def metadata(self):
metadata = SortedDict() metadata = collections.OrderedDict()
metadata['type'] = self.type_label metadata['type'] = self.type_label
metadata['required'] = getattr(self, 'required', False) metadata['required'] = getattr(self, 'required', False)
optional_attrs = ['read_only', 'label', 'help_text', optional_attrs = ['read_only', 'label', 'help_text',

View File

@ -16,11 +16,10 @@ For example, you might have a `urls.py` that looks something like this:
from __future__ import unicode_literals from __future__ import unicode_literals
import itertools import itertools
from collections import namedtuple from collections import namedtuple, OrderedDict
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import NoReverseMatch from django.core.urlresolvers import NoReverseMatch
from django.utils.datastructures import SortedDict
from rest_framework import views from rest_framework import views
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
@ -278,7 +277,7 @@ class DefaultRouter(SimpleRouter):
""" """
Return a view to use as the API root. Return a view to use as the API root.
""" """
api_root_dict = SortedDict() api_root_dict = OrderedDict()
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)
@ -287,7 +286,7 @@ class DefaultRouter(SimpleRouter):
_ignore_model_permissions = True _ignore_model_permissions = True
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
ret = SortedDict() ret = OrderedDict()
for key, url_name in api_root_dict.items(): for key, url_name in api_root_dict.items():
try: try:
ret[key] = reverse( ret[key] = reverse(

View File

@ -11,6 +11,7 @@ python primitives.
response content is handled by parsers and renderers. response content is handled by parsers and renderers.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import OrderedDict
import copy import copy
import datetime import datetime
import inspect import inspect
@ -21,7 +22,6 @@ from django.core.paginator import Page
from django.db import models from django.db import models
from django.forms import widgets from django.forms import widgets
from django.utils import six from django.utils import six
from django.utils.datastructures import SortedDict
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
@ -106,7 +106,7 @@ class DictWithMetadata(dict):
return dict(self) return dict(self)
class SortedDictWithMetadata(SortedDict): class OrderedDictWithMetadata(OrderedDict):
""" """
A sorted dict-like object, that can have additional properties attached. A sorted dict-like object, that can have additional properties attached.
""" """
@ -116,7 +116,7 @@ class SortedDictWithMetadata(SortedDict):
Overriden to remove the metadata from the dict, since it shouldn't be Overriden to remove the metadata from the dict, since it shouldn't be
pickle and may in some instances be unpickleable. pickle and may in some instances be unpickleable.
""" """
return SortedDict(self).__dict__ return OrderedDict(self).__dict__
def _is_protected_type(obj): def _is_protected_type(obj):
@ -152,7 +152,7 @@ def _get_declared_fields(bases, attrs):
if hasattr(base, 'base_fields'): if hasattr(base, 'base_fields'):
fields = list(base.base_fields.items()) + fields fields = list(base.base_fields.items()) + fields
return SortedDict(fields) return OrderedDict(fields)
class SerializerMetaclass(type): class SerializerMetaclass(type):
@ -180,7 +180,7 @@ class BaseSerializer(WritableField):
pass pass
_options_class = SerializerOptions _options_class = SerializerOptions
_dict_class = SortedDictWithMetadata _dict_class = OrderedDictWithMetadata
def __init__(self, instance=None, data=None, files=None, def __init__(self, instance=None, data=None, files=None,
context=None, partial=False, many=False, context=None, partial=False, many=False,
@ -229,7 +229,7 @@ class BaseSerializer(WritableField):
This will be the set of any explicitly declared fields, This will be the set of any explicitly declared fields,
plus the set of fields returned by get_default_fields(). plus the set of fields returned by get_default_fields().
""" """
ret = SortedDict() ret = OrderedDict()
# Get the explicitly declared fields # Get the explicitly declared fields
base_fields = copy.deepcopy(self.base_fields) base_fields = copy.deepcopy(self.base_fields)
@ -245,7 +245,7 @@ class BaseSerializer(WritableField):
# If 'fields' is specified, use those fields, in that order. # If 'fields' is specified, use those fields, in that order.
if self.opts.fields: if self.opts.fields:
assert isinstance(self.opts.fields, (list, tuple)), '`fields` must be a list or tuple' assert isinstance(self.opts.fields, (list, tuple)), '`fields` must be a list or tuple'
new = SortedDict() new = OrderedDict()
for key in self.opts.fields: for key in self.opts.fields:
new[key] = ret[key] new[key] = ret[key]
ret = new ret = new
@ -606,7 +606,7 @@ class BaseSerializer(WritableField):
Useful for things like responding to OPTIONS requests, or generating Useful for things like responding to OPTIONS requests, or generating
API schemas for auto-documentation. API schemas for auto-documentation.
""" """
return SortedDict( return OrderedDict(
[ [
(field_name, field.metadata()) (field_name, field.metadata())
for field_name, field in six.iteritems(self.fields) for field_name, field in six.iteritems(self.fields)
@ -683,7 +683,7 @@ class ModelSerializer(Serializer):
self.__class__.__name__ self.__class__.__name__
) )
opts = cls._meta.concrete_model._meta opts = cls._meta.concrete_model._meta
ret = SortedDict() ret = OrderedDict()
nested = bool(self.opts.depth) nested = bool(self.opts.depth)
# Deal with adding the primary key field # Deal with adding the primary key field
@ -985,13 +985,16 @@ class ModelSerializer(Serializer):
if field_name in attrs: if field_name in attrs:
m2m_data[field_name] = attrs.pop(field_name) m2m_data[field_name] = attrs.pop(field_name)
# Forward m2m relations def _inner_loop_code(field):
for field in meta.many_to_many + meta.virtual_fields:
if isinstance(field, GenericForeignKey): if isinstance(field, GenericForeignKey):
continue return
if field.name in attrs: if field.name in attrs:
m2m_data[field.name] = attrs.pop(field.name) m2m_data[field.name] = attrs.pop(field.name)
# Forward m2m relations
_ = [_inner_loop_code(field) for field in meta.many_to_many]
_ = [_inner_loop_code(field) for field in meta.virtual_fields]
# Nested forward relations - These need to be marked so we can save # Nested forward relations - These need to be marked so we can save
# them before saving the parent model instance. # them before saving the parent model instance.
for field_name in attrs.keys(): for field_name in attrs.keys():

View File

@ -2,12 +2,12 @@
Helper classes for parsers. Helper classes for parsers.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import OrderedDict
from django.utils import timezone from django.utils import timezone
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.utils.datastructures import SortedDict
from django.utils.functional import Promise from django.utils.functional import Promise
from rest_framework.compat import force_text from rest_framework.compat import force_text
from rest_framework.serializers import DictWithMetadata, SortedDictWithMetadata from rest_framework.serializers import DictWithMetadata, OrderedDictWithMetadata
import datetime import datetime
import decimal import decimal
import types import types
@ -67,7 +67,7 @@ else:
class SafeDumper(yaml.SafeDumper): class SafeDumper(yaml.SafeDumper):
""" """
Handles decimals as strings. Handles decimals as strings.
Handles SortedDicts as usual dicts, but preserves field order, rather Handles OrderedDicts as usual dicts, but preserves field order, rather
than the usual behaviour of sorting the keys. than the usual behaviour of sorting the keys.
""" """
def represent_decimal(self, data): def represent_decimal(self, data):
@ -81,7 +81,7 @@ else:
best_style = True best_style = True
if hasattr(mapping, 'items'): if hasattr(mapping, 'items'):
mapping = list(mapping.items()) mapping = list(mapping.items())
if not isinstance(mapping, SortedDict): if not isinstance(mapping, OrderedDict):
mapping.sort() mapping.sort()
for item_key, item_value in mapping: for item_key, item_value in mapping:
node_key = self.represent_data(item_key) node_key = self.represent_data(item_key)
@ -103,7 +103,7 @@ else:
SafeDumper.represent_decimal SafeDumper.represent_decimal
) )
SafeDumper.add_representer( SafeDumper.add_representer(
SortedDict, OrderedDict,
yaml.representer.SafeRepresenter.represent_dict yaml.representer.SafeRepresenter.represent_dict
) )
SafeDumper.add_representer( SafeDumper.add_representer(
@ -111,7 +111,7 @@ else:
yaml.representer.SafeRepresenter.represent_dict yaml.representer.SafeRepresenter.represent_dict
) )
SafeDumper.add_representer( SafeDumper.add_representer(
SortedDictWithMetadata, OrderedDictWithMetadata,
yaml.representer.SafeRepresenter.represent_dict yaml.representer.SafeRepresenter.represent_dict
) )
SafeDumper.add_representer( SafeDumper.add_representer(

View File

@ -3,9 +3,9 @@ Provides an APIView class that is the base of all views in REST framework.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
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.datastructures import SortedDict
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from rest_framework import status, exceptions from rest_framework import status, exceptions
from rest_framework.compat import smart_text, HttpResponseBase, View from rest_framework.compat import smart_text, HttpResponseBase, View
@ -421,7 +421,7 @@ class APIView(View):
# By default we can't provide any form-like information, however the # By default we can't provide any form-like information, however the
# generic views override this implementation and add additional # generic views override this implementation and add additional
# information for POST and PUT methods, based on the serializer. # information for POST and PUT methods, based on the serializer.
ret = SortedDict() ret = OrderedDict()
ret['name'] = self.get_view_name() ret['name'] = self.get_view_name()
ret['description'] = self.get_view_description() ret['description'] = self.get_view_description()
ret['renders'] = [renderer.media_type for renderer in self.renderer_classes] ret['renders'] = [renderer.media_type for renderer in self.renderer_classes]