Skip to content

Commit ad5a793

Browse files
slivercauvipy
andauthored
Replaced OrderedDict with dict (#1132)
* try using python dict instead of ordered dict in metadata * try using python dict instead of ordered dict in pagination field * try using python dict instead of ordered dict in relations * Adjusted to dict syntax * Removed OrderedDict from renderers.py * Removed OrderedDict in serializers, utils and views * Simplified creating of dicts in renderers.py * Added CHANGELOG entry --------- Co-authored-by: Asif Saif Uddin <[email protected]>
1 parent 5c88b93 commit ad5a793

File tree

9 files changed

+83
-135
lines changed

9 files changed

+83
-135
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ any parts of the framework not mentioned in the documentation should generally b
1818

1919
* Added support to overwrite serializer methods in customized schema class
2020
* Adjusted some still old formatted strings to f-strings.
21+
* Replaced `OrderedDict` with `dict` which is also ordered since Python 3.7.
2122

2223
### Fixed
2324

rest_framework_json_api/metadata.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from collections import OrderedDict
2-
31
from django.db.models.fields import related
42
from django.utils.encoding import force_str
53
from rest_framework import serializers
@@ -65,7 +63,7 @@ class JSONAPIMetadata(SimpleMetadata):
6563
)
6664

6765
def determine_metadata(self, request, view):
68-
metadata = OrderedDict()
66+
metadata = {}
6967
metadata["name"] = view.get_view_name()
7068
metadata["description"] = view.get_view_description()
7169
metadata["renders"] = [
@@ -92,19 +90,17 @@ def get_serializer_info(self, serializer):
9290
# Remove the URL field if present
9391
serializer.fields.pop(api_settings.URL_FIELD_NAME, None)
9492

95-
return OrderedDict(
96-
[
97-
(format_field_name(field_name), self.get_field_info(field))
98-
for field_name, field in serializer.fields.items()
99-
]
100-
)
93+
return {
94+
format_field_name(field_name): self.get_field_info(field)
95+
for field_name, field in serializer.fields.items()
96+
}
10197

10298
def get_field_info(self, field):
10399
"""
104100
Given an instance of a serializer field, return a dictionary
105101
of metadata about it.
106102
"""
107-
field_info = OrderedDict()
103+
field_info = {}
108104
serializer = field.parent
109105

110106
if isinstance(field, serializers.ManyRelatedField):

rest_framework_json_api/pagination.py

+22-31
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""
22
Pagination fields
33
"""
4-
from collections import OrderedDict
54

65
from rest_framework.pagination import LimitOffsetPagination, PageNumberPagination
76
from rest_framework.utils.urls import remove_query_param, replace_query_param
@@ -36,22 +35,18 @@ def get_paginated_response(self, data):
3635
{
3736
"results": data,
3837
"meta": {
39-
"pagination": OrderedDict(
40-
[
41-
("page", self.page.number),
42-
("pages", self.page.paginator.num_pages),
43-
("count", self.page.paginator.count),
44-
]
45-
)
38+
"pagination": {
39+
"page": self.page.number,
40+
"pages": self.page.paginator.num_pages,
41+
"count": self.page.paginator.count,
42+
}
43+
},
44+
"links": {
45+
"first": self.build_link(1),
46+
"last": self.build_link(self.page.paginator.num_pages),
47+
"next": self.build_link(next),
48+
"prev": self.build_link(previous),
4649
},
47-
"links": OrderedDict(
48-
[
49-
("first", self.build_link(1)),
50-
("last", self.build_link(self.page.paginator.num_pages)),
51-
("next", self.build_link(next)),
52-
("prev", self.build_link(previous)),
53-
]
54-
),
5550
}
5651
)
5752

@@ -97,21 +92,17 @@ def get_paginated_response(self, data):
9792
{
9893
"results": data,
9994
"meta": {
100-
"pagination": OrderedDict(
101-
[
102-
("count", self.count),
103-
("limit", self.limit),
104-
("offset", self.offset),
105-
]
106-
)
95+
"pagination": {
96+
"count": self.count,
97+
"limit": self.limit,
98+
"offset": self.offset,
99+
}
100+
},
101+
"links": {
102+
"first": self.get_first_link(),
103+
"last": self.get_last_link(),
104+
"next": self.get_next_link(),
105+
"prev": self.get_previous_link(),
107106
},
108-
"links": OrderedDict(
109-
[
110-
("first", self.get_first_link()),
111-
("last", self.get_last_link()),
112-
("next", self.get_next_link()),
113-
("prev", self.get_previous_link()),
114-
]
115-
),
116107
}
117108
)

rest_framework_json_api/relations.py

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import json
2-
from collections import OrderedDict
32

43
import inflection
54
from django.core.exceptions import ImproperlyConfigured
@@ -104,7 +103,7 @@ def get_url(self, name, view_name, kwargs, request):
104103
def get_links(self, obj=None, lookup_field="pk"):
105104
request = self.context.get("request", None)
106105
view = self.context.get("view", None)
107-
return_data = OrderedDict()
106+
return_data = {}
108107

109108
kwargs = {
110109
lookup_field: getattr(obj, lookup_field)
@@ -257,7 +256,7 @@ def to_representation(self, value):
257256
if resource_type is None or not self._skip_polymorphic_optimization:
258257
resource_type = get_resource_type_from_instance(value)
259258

260-
return OrderedDict([("type", resource_type), ("id", str(pk))])
259+
return {"type": resource_type, "id": str(pk)}
261260

262261
def get_resource_type_from_included_serializer(self):
263262
"""
@@ -301,12 +300,10 @@ def get_choices(self, cutoff=None):
301300
if cutoff is not None:
302301
queryset = queryset[:cutoff]
303302

304-
return OrderedDict(
305-
[
306-
(json.dumps(self.to_representation(item)), self.display_value(item))
307-
for item in queryset
308-
]
309-
)
303+
return {
304+
json.dumps(self.to_representation(item)): self.display_value(item)
305+
for item in queryset
306+
}
310307

311308

312309
class PolymorphicResourceRelatedField(ResourceRelatedField):

rest_framework_json_api/renderers.py

+31-49
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
Renderers
33
"""
44
import copy
5-
from collections import OrderedDict, defaultdict
5+
from collections import defaultdict
66
from collections.abc import Iterable
77

88
import inflection
99
from django.db.models import Manager
1010
from django.template import loader
11-
from django.utils import encoding
11+
from django.utils.encoding import force_str
1212
from rest_framework import relations, renderers
1313
from rest_framework.fields import SkipField, get_attribute
1414
from rest_framework.relations import PKOnlyObject
@@ -56,7 +56,7 @@ def extract_attributes(cls, fields, resource):
5656
"""
5757
Builds the `attributes` object of the JSON:API resource object.
5858
"""
59-
data = OrderedDict()
59+
data = {}
6060
for field_name, field in iter(fields.items()):
6161
# ID is always provided in the root of JSON:API so remove it from attributes
6262
if field_name == "id":
@@ -89,7 +89,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
8989
# Avoid circular deps
9090
from rest_framework_json_api.relations import ResourceRelatedField
9191

92-
data = OrderedDict()
92+
data = {}
9393

9494
# Don't try to extract relationships from a non-existent resource
9595
if resource_instance is None:
@@ -125,16 +125,10 @@ def extract_relationships(cls, fields, resource, resource_instance):
125125
relation_instance if relation_instance is not None else list()
126126
)
127127

128-
for related_object in relation_queryset:
129-
relation_data.append(
130-
OrderedDict(
131-
[
132-
("type", relation_type),
133-
("id", encoding.force_str(related_object.pk)),
134-
]
135-
)
136-
)
137-
128+
relation_data = [
129+
{"type": relation_type, "id": force_str(related_object.pk)}
130+
for related_object in relation_queryset
131+
]
138132
data.update(
139133
{
140134
field_name: {
@@ -171,18 +165,12 @@ def extract_relationships(cls, fields, resource, resource_instance):
171165
if not resolved:
172166
continue
173167
relation_id = relation if resource.get(field_name) else None
174-
relation_data = {
175-
"data": (
176-
OrderedDict(
177-
[
178-
("type", relation_type),
179-
("id", encoding.force_str(relation_id)),
180-
]
181-
)
182-
if relation_id is not None
183-
else None
184-
)
185-
}
168+
relation_data = {"data": None}
169+
if relation_id is not None:
170+
relation_data["data"] = {
171+
"type": relation_type,
172+
"id": force_str(relation_id),
173+
}
186174

187175
if isinstance(
188176
field, relations.HyperlinkedRelatedField
@@ -233,12 +221,10 @@ def extract_relationships(cls, fields, resource, resource_instance):
233221
)
234222

235223
relation_data.append(
236-
OrderedDict(
237-
[
238-
("type", nested_resource_instance_type),
239-
("id", encoding.force_str(nested_resource_instance.pk)),
240-
]
241-
)
224+
{
225+
"type": nested_resource_instance_type,
226+
"id": force_str(nested_resource_instance.pk),
227+
}
242228
)
243229
data.update(
244230
{
@@ -419,7 +405,7 @@ def extract_meta(cls, serializer, resource):
419405
else:
420406
meta = getattr(serializer, "Meta", None)
421407
meta_fields = getattr(meta, "meta_fields", [])
422-
data = OrderedDict()
408+
data = {}
423409
for field_name in meta_fields:
424410
data.update({field_name: resource.get(field_name)})
425411
return data
@@ -457,37 +443,33 @@ def build_json_resource_obj(
457443
# Determine type from the instance if the underlying model is polymorphic
458444
if force_type_resolution:
459445
resource_name = utils.get_resource_type_from_instance(resource_instance)
460-
resource_data = [
461-
("type", resource_name),
462-
(
463-
"id",
464-
encoding.force_str(resource_instance.pk) if resource_instance else None,
465-
),
466-
("attributes", cls.extract_attributes(fields, resource)),
467-
]
446+
resource_id = force_str(resource_instance.pk) if resource_instance else None
447+
resource_data = {
448+
"type": resource_name,
449+
"id": resource_id,
450+
"attributes": cls.extract_attributes(fields, resource),
451+
}
468452
relationships = cls.extract_relationships(fields, resource, resource_instance)
469453
if relationships:
470-
resource_data.append(("relationships", relationships))
454+
resource_data["relationships"] = relationships
471455
# Add 'self' link if field is present and valid
472456
if api_settings.URL_FIELD_NAME in resource and isinstance(
473457
fields[api_settings.URL_FIELD_NAME], relations.RelatedField
474458
):
475-
resource_data.append(
476-
("links", {"self": resource[api_settings.URL_FIELD_NAME]})
477-
)
459+
resource_data["links"] = {"self": resource[api_settings.URL_FIELD_NAME]}
478460

479461
meta = cls.extract_meta(serializer, resource)
480462
if meta:
481-
resource_data.append(("meta", utils.format_field_names(meta)))
463+
resource_data["meta"] = utils.format_field_names(meta)
482464

483-
return OrderedDict(resource_data)
465+
return resource_data
484466

485467
def render_relationship_view(
486468
self, data, accepted_media_type=None, renderer_context=None
487469
):
488470
# Special case for RelationshipView
489471
view = renderer_context.get("view", None)
490-
render_data = OrderedDict([("data", data)])
472+
render_data = {"data": data}
491473
links = view.get_links()
492474
if links:
493475
render_data.update({"links": links}),
@@ -615,7 +597,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
615597
)
616598

617599
# Make sure we render data in a specific order
618-
render_data = OrderedDict()
600+
render_data = {}
619601

620602
if isinstance(data, dict) and data.get("links"):
621603
render_data["links"] = data.get("links")

rest_framework_json_api/serializers.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from collections import OrderedDict
21
from collections.abc import Mapping
32

43
import inflection
@@ -95,7 +94,7 @@ def __init__(self, *args, **kwargs):
9594
pass
9695
else:
9796
fieldset = request.query_params.get(param_name).split(",")
98-
# iterate over a *copy* of self.fields' underlying OrderedDict, because we may
97+
# iterate over a *copy* of self.fields' underlying dict, because we may
9998
# modify the original during the iteration.
10099
# self.fields is a `rest_framework.utils.serializer_helpers.BindingDict`
101100
for field_name, _field in self.fields.fields.copy().items():
@@ -305,7 +304,7 @@ def get_field_names(self, declared_fields, info):
305304
"""
306305
meta_fields = getattr(self.Meta, "meta_fields", [])
307306

308-
declared = OrderedDict()
307+
declared = {}
309308
for field_name in set(declared_fields.keys()):
310309
field = declared_fields[field_name]
311310
if field_name not in meta_fields:

rest_framework_json_api/utils.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import inspect
22
import operator
3-
from collections import OrderedDict
43

54
import inflection
65
from django.conf import settings
@@ -107,11 +106,7 @@ def format_field_names(obj, format_type=None):
107106
format_type = json_api_settings.FORMAT_FIELD_NAMES
108107

109108
if isinstance(obj, dict):
110-
formatted = OrderedDict()
111-
for key, value in obj.items():
112-
key = format_value(key, format_type)
113-
formatted[key] = value
114-
return formatted
109+
return {format_value(key, format_type): value for key, value in obj.items()}
115110

116111
return obj
117112

rest_framework_json_api/views.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from rest_framework_json_api.serializers import ResourceIdentifierObjectSerializer
2424
from rest_framework_json_api.utils import (
2525
Hyperlink,
26-
OrderedDict,
2726
get_included_resources,
2827
get_resource_type_from_instance,
2928
undo_format_link_segment,
@@ -275,7 +274,7 @@ def get_url(self, name, view_name, kwargs, request):
275274
return Hyperlink(url, name)
276275

277276
def get_links(self):
278-
return_data = OrderedDict()
277+
return_data = {}
279278
self_link = self.get_url(
280279
"self", self.self_link_view_name, self.kwargs, self.request
281280
)
@@ -284,9 +283,9 @@ def get_links(self):
284283
"related", self.related_link_view_name, related_kwargs, self.request
285284
)
286285
if self_link:
287-
return_data.update({"self": self_link})
286+
return_data["self"] = self_link
288287
if related_link:
289-
return_data.update({"related": related_link})
288+
return_data["related"] = related_link
290289
return return_data
291290

292291
def get(self, request, *args, **kwargs):

0 commit comments

Comments
 (0)