|
2 | 2 | Renderers
|
3 | 3 | """
|
4 | 4 | import copy
|
5 |
| -from collections import OrderedDict, defaultdict |
| 5 | +from collections import defaultdict |
6 | 6 | from collections.abc import Iterable
|
7 | 7 |
|
8 | 8 | import inflection
|
9 | 9 | from django.db.models import Manager
|
10 | 10 | from django.template import loader
|
11 |
| -from django.utils import encoding |
| 11 | +from django.utils.encoding import force_str |
12 | 12 | from rest_framework import relations, renderers
|
13 | 13 | from rest_framework.fields import SkipField, get_attribute
|
14 | 14 | from rest_framework.relations import PKOnlyObject
|
@@ -56,7 +56,7 @@ def extract_attributes(cls, fields, resource):
|
56 | 56 | """
|
57 | 57 | Builds the `attributes` object of the JSON:API resource object.
|
58 | 58 | """
|
59 |
| - data = OrderedDict() |
| 59 | + data = {} |
60 | 60 | for field_name, field in iter(fields.items()):
|
61 | 61 | # ID is always provided in the root of JSON:API so remove it from attributes
|
62 | 62 | if field_name == "id":
|
@@ -89,7 +89,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
|
89 | 89 | # Avoid circular deps
|
90 | 90 | from rest_framework_json_api.relations import ResourceRelatedField
|
91 | 91 |
|
92 |
| - data = OrderedDict() |
| 92 | + data = {} |
93 | 93 |
|
94 | 94 | # Don't try to extract relationships from a non-existent resource
|
95 | 95 | if resource_instance is None:
|
@@ -125,16 +125,10 @@ def extract_relationships(cls, fields, resource, resource_instance):
|
125 | 125 | relation_instance if relation_instance is not None else list()
|
126 | 126 | )
|
127 | 127 |
|
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 | + ] |
138 | 132 | data.update(
|
139 | 133 | {
|
140 | 134 | field_name: {
|
@@ -171,18 +165,12 @@ def extract_relationships(cls, fields, resource, resource_instance):
|
171 | 165 | if not resolved:
|
172 | 166 | continue
|
173 | 167 | 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 | + } |
186 | 174 |
|
187 | 175 | if isinstance(
|
188 | 176 | field, relations.HyperlinkedRelatedField
|
@@ -233,12 +221,10 @@ def extract_relationships(cls, fields, resource, resource_instance):
|
233 | 221 | )
|
234 | 222 |
|
235 | 223 | 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 | + } |
242 | 228 | )
|
243 | 229 | data.update(
|
244 | 230 | {
|
@@ -419,7 +405,7 @@ def extract_meta(cls, serializer, resource):
|
419 | 405 | else:
|
420 | 406 | meta = getattr(serializer, "Meta", None)
|
421 | 407 | meta_fields = getattr(meta, "meta_fields", [])
|
422 |
| - data = OrderedDict() |
| 408 | + data = {} |
423 | 409 | for field_name in meta_fields:
|
424 | 410 | data.update({field_name: resource.get(field_name)})
|
425 | 411 | return data
|
@@ -457,37 +443,33 @@ def build_json_resource_obj(
|
457 | 443 | # Determine type from the instance if the underlying model is polymorphic
|
458 | 444 | if force_type_resolution:
|
459 | 445 | 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 | + } |
468 | 452 | relationships = cls.extract_relationships(fields, resource, resource_instance)
|
469 | 453 | if relationships:
|
470 |
| - resource_data.append(("relationships", relationships)) |
| 454 | + resource_data["relationships"] = relationships |
471 | 455 | # Add 'self' link if field is present and valid
|
472 | 456 | if api_settings.URL_FIELD_NAME in resource and isinstance(
|
473 | 457 | fields[api_settings.URL_FIELD_NAME], relations.RelatedField
|
474 | 458 | ):
|
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]} |
478 | 460 |
|
479 | 461 | meta = cls.extract_meta(serializer, resource)
|
480 | 462 | if meta:
|
481 |
| - resource_data.append(("meta", utils.format_field_names(meta))) |
| 463 | + resource_data["meta"] = utils.format_field_names(meta) |
482 | 464 |
|
483 |
| - return OrderedDict(resource_data) |
| 465 | + return resource_data |
484 | 466 |
|
485 | 467 | def render_relationship_view(
|
486 | 468 | self, data, accepted_media_type=None, renderer_context=None
|
487 | 469 | ):
|
488 | 470 | # Special case for RelationshipView
|
489 | 471 | view = renderer_context.get("view", None)
|
490 |
| - render_data = OrderedDict([("data", data)]) |
| 472 | + render_data = {"data": data} |
491 | 473 | links = view.get_links()
|
492 | 474 | if links:
|
493 | 475 | render_data.update({"links": links}),
|
@@ -615,7 +597,7 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
|
615 | 597 | )
|
616 | 598 |
|
617 | 599 | # Make sure we render data in a specific order
|
618 |
| - render_data = OrderedDict() |
| 600 | + render_data = {} |
619 | 601 |
|
620 | 602 | if isinstance(data, dict) and data.get("links"):
|
621 | 603 | render_data["links"] = data.get("links")
|
|
0 commit comments