【问题标题】:'collections.OrderedDict' object has no attribute 'uuid' - Django REST Framework'collections.OrderedDict' 对象没有属性 'uuid' - Django REST Framework
【发布时间】:2021-05-02 17:24:23
【问题描述】:

我正在使用django-mptt 为我的Section 模型创建一个树状结构。不幸的是,当我用drf-writable-nested 对其进行序列化时,我得到了一个错误。仅当将url 字段添加到序列化程序时才会出现此错误。

此外,当我从自定义查找字段中删除 uuid 时,错误只是替换为 pk

我发现了这个:https://stackoverflow.com/a/55173445/9137820,但我没有直接访问任何数据,所以我不确定这可能是什么问题。

代码:

# 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 (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'

【问题讨论】:

    标签: django django-rest-framework django-mptt


    【解决方案1】:

    我做了一些挖掘,这就是我能找到的。字典和 OrderedDicts 不会将键和值保存为类属性。所以你不能使用getattr() 来检索它们。您需要从OrderedDict 请求一个方法或属性,如dict.keys()dict.values()。不能使用键名。

    看这个例子:

    from collections import OrderedDict
    
    g = OrderedDict()
    
    g['test'] = 1
    
    g = getattr(g, 'values')
    
    print(list(g())[0])
    

    这很好,但如果你改变了

    g = getattr(g, 'values')
    

    g = getattr(g, 'test')
    

    它会产生与您遇到的相同的错误

    【讨论】:

    • 同样的错误,不幸的是。我注意到一件奇怪的事情:OrderedDict 具有uuid 属性。 OrderedDict([('uuid', 'e8d3d17b-55f0-415c-b279-9e32e869e0fb'), ('name', 'Testing'), ('get_children', [])])
    • 使用不同的字段是否会产生相同的错误?例如使用name 而不是uuid?
    • 是的,如果我完全删除自定义查找字段,uuid 将替换为 pk
    • 我发现您不能为此使用像 uuid 这样的键名。请参阅我的更新答案以获得解释。
    • 我自己没有使用getattr,它被我在某处使用的库调用。
    猜你喜欢
    • 2018-03-30
    • 1970-01-01
    • 2015-10-15
    • 2019-04-30
    • 2017-03-04
    • 2021-02-04
    • 2018-09-13
    • 2020-12-24
    • 2011-10-13
    相关资源
    最近更新 更多