13
13
from django .http import Http404
14
14
from django .utils import encoding
15
15
from django .utils .translation import gettext_lazy as _
16
- from rest_framework import exceptions
16
+ from rest_framework import exceptions , relations
17
17
from rest_framework .exceptions import APIException
18
18
19
19
from .settings import json_api_settings
@@ -368,6 +368,23 @@ def get_relation_instance(resource_instance, source, serializer):
368
368
return True , relation_instance
369
369
370
370
371
+ def get_serializer_from_context (context ):
372
+ if hasattr (context ["view" ], "get_serializer" ):
373
+ return context ["view" ].get_serializer ()
374
+ elif hasattr (context ["view" ], "get_serializer_class" ):
375
+ return context ["view" ].get_serializer_class ()()
376
+ elif hasattr (context ["view" ], "serializer_class" ):
377
+ return context ["view" ].serializer_class ()
378
+
379
+
380
+ def get_relationship_fields (fields ):
381
+ return {
382
+ name : field
383
+ for name , field in fields .items ()
384
+ if isinstance (field , (relations .RelatedField , relations .ManyRelatedField ))
385
+ }
386
+
387
+
371
388
class Hyperlink (str ):
372
389
"""
373
390
A string like object that additionally has an associated name.
@@ -394,9 +411,14 @@ def format_drf_errors(response, context, exc):
394
411
errors .extend (format_error_object (message , "/data" , response ))
395
412
# handle all errors thrown from serializers
396
413
else :
414
+ serializer = get_serializer_from_context (context )
415
+ fields = get_serializer_fields (serializer ) or dict ()
416
+ relationship_fields = get_relationship_fields (fields )
417
+
397
418
for field , error in response .data .items ():
398
419
field = format_field_name (field )
399
- pointer = "/data/attributes/{}" .format (field )
420
+ rel = "relationships" if field in relationship_fields else "attributes"
421
+ pointer = "/data/{}/{}" .format (rel , field )
400
422
if isinstance (exc , Http404 ) and isinstance (error , str ):
401
423
# 404 errors don't have a pointer
402
424
errors .extend (format_error_object (error , None , response ))
0 commit comments