Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
347 views
in Technique[技术] by (71.8m points)

'collections.OrderedDict' object has no attribute 'uuid' - Django REST Framework

I'm using django-mptt to create a tree-like structure for my Section model. Unfortunately, when I go to serialize it with drf-writable-nested, I get an error. This error only occurs when the url field is added to the serializer.

Also, when I remove uuid from the custom lookup field, the error is just replaced with pk.

I found this: https://stackoverflow.com/a/55173445/9137820, but I'm not accessing any of the data directly, so I'm not sure how that could be the issue.

Code:

# models.py

class Section(MPTTModel, TimeStampedModel):
    uuid = models.UUIDField(default=uuid_lib.uuid4, editable=False)
    name = models.CharField(max_length=255, unique=True)
    objects = TreeManager()
    parent = TreeForeignKey('self', related_name='section_children', on_delete=models.CASCADE, null=True, blank=True)
# serializers.py

class SectionSerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
    children = serializers.ListField(source='get_children', child=RecursiveField())

    class Meta:
        model = Section
        fields = ['url', 'uuid', 'name', 'children']

        extra_kwargs = {
            'url': {'lookup_field': 'uuid'},
        }
# views.py

class SectionDetail(generics.RetrieveUpdateDestroyAPIView, viewsets.GenericViewSet):
    queryset = Section.objects.all()
    serializer_class = SectionSerializer
    lookup_field = 'uuid'

Traceback:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 75, in update
    return Response(serializer.data)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 548, in data
    ret = super().data
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 515, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/fields.py", line 1661, in to_representation
    return [self.child.to_representation(item) if item is not None else None for item in data]
  File "/usr/local/lib/python3.9/site-packages/rest_framework/fields.py", line 1661, in <listcomp>
    return [self.child.to_representation(item) if item is not None else None for item in data]
  File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 515, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/relations.py", line 399, in to_representation
    url = self.get_url(value, self.view_name, request, format)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/relations.py", line 335, in get_url
    lookup_value = getattr(obj, self.lookup_field)

Exception Type: AttributeError at /api/v1/sections/3b15cbda-f61e-4a00-89fb-817beed10b14/
Exception Value: 'collections.OrderedDict' object has no attribute 'uuid'
question from:https://stackoverflow.com/questions/65943501/collections-ordereddict-object-has-no-attribute-uuid-django-rest-framework

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I did some digging and this is what I can find. Dictionaries and OrderedDicts don't save keys and values as class attributes. So you cant retrieve them using getattr(). You need to request a method or attribute like dict.keys() or dict.values() from the OrderedDict. You can't use a key name.

See this example:

from collections import OrderedDict

g = OrderedDict()

g['test'] = 1

g = getattr(g, 'values')

print(list(g())[0])

That works fine but if you changed

g = getattr(g, 'values')

to

g = getattr(g, 'test')

It produces the same error you're experiencing


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...