Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AttributeError: 'OrderedDict' object has no attribute 'pk' #2964

Closed
aidanlister opened this issue May 24, 2015 · 4 comments
Closed

AttributeError: 'OrderedDict' object has no attribute 'pk' #2964

aidanlister opened this issue May 24, 2015 · 4 comments

Comments

@aidanlister
Copy link

views:

@detail_route(methods=['post'])
def quote(self, request, pk):
    task = self.get_object()

    serializer = serializers.TaskCreateQuoteSerializer(data=request.DATA, task=task)

    if not serializer.is_valid():
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    # this causes a problem
    serializer.data['servicetasks']:

serializers:

class TaskCreateQuoteSerializer(serializers.Serializer):
    servicetasks = serializers.PrimaryKeyRelatedField(many=True, required=True, allow_null=False,
        queryset=ServiceTask.objects.all())

    def __init__(self, task, *args, **kwargs):
        super(TaskCreateQuoteSerializer, self).__init__(*args, **kwargs)
        # print task.servicetask_set.all()
        # self.fields['servicetasks'].queryset = task.servicetask_set.all()

When I try and print the serializer:

TaskCreateQuoteSerializer(data={u'servicetasks': [3115, 3114]}, task=<Task: E13/688 COMPLETE>):
    servicetasks = PrimaryKeyRelatedField(allow_null=False, many=True, queryset=[<ServiceTask: Ser...]

So whenever I try and access serializer.data I get an exception:

AttributeError: 'OrderedDict' object has no attribute 'pk'


Traceback:
File "/usr/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
  57.         return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/rest_framework/viewsets.py" in view
  85.             return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  452.             response = self.handle_exception(exc)
File "/usr/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
  449.             response = handler(request, *args, **kwargs)
File "/usr/src/app/abas/apps/api/views.py" in quote
  270.         if not serializer.data['servicetasks']:
File "/usr/local/lib/python2.7/site-packages/rest_framework/serializers.py" in data
  466.         ret = super(Serializer, self).data
File "/usr/local/lib/python2.7/site-packages/rest_framework/serializers.py" in data
  215.                 self._data = self.to_representation(self.validated_data)
File "/usr/local/lib/python2.7/site-packages/rest_framework/serializers.py" in to_representation
  426.                 attribute = field.get_attribute(instance)
File "/usr/local/lib/python2.7/site-packages/rest_framework/relations.py" in get_attribute
  364.         if not instance.pk:
@tomchristie
Copy link
Member

The serializer.data property is only valid if you have a saved instance to serializer.
Either call serializer.save() or use serializer.validated_data to access data prior to saving.
We should consider an explicit guard against this usage.

@thenewguy
Copy link

I encountered this as well using the detail_route decorator for a similar purpose. Took a long time to figure out what was going on. It would be helpful if there was a guard against this that stated your previous response of The serializer.data property is only valid if you have a saved instance to serializer. Either call serializer.save() or use serializer.validated_data to access date prior to saving.

@xordoquy
Copy link
Collaborator

xordoquy commented Sep 8, 2015

@tomchristie The current error here is while accessing the data so we can't say "Either call serializer.save() or use serializer.validated_data to access date prior to saving." since the later doesn't work anyway in that case.

Edited.

@xordoquy
Copy link
Collaborator

xordoquy commented Sep 8, 2015

Question is: do we want data to be filled with validated_data if there's no errors.
I think we could remove - through deprecation - lines 224/225 at https://github.com/tomchristie/django-rest-framework/blob/8d7c0a8474583df6b27d0d5be8a84bd9a154ab35/rest_framework/serializers.py#L224

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants