簡體   English   中英

Django AttributeError: 'collections.OrderedDict' 對象沒有屬性 'pk'

[英]Django AttributeError: 'collections.OrderedDict' object has no attribute 'pk'

當我嘗試向模型添加 url 屬性時,出現此錯誤:

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

這些是我使用的代碼。 我嘗試了很多東西,但我嘗試的一切都出錯了..

序列化器:

class GroupPatchSerializer(serializers.ModelSerializer):
    linked_sites = serializers.ListField()
    name = serializers.CharField(required=False)
    url = serializers.HyperlinkedIdentityField(
        view_name="group-detail", lookup_url_kwarg="group_pk"
    )

    class Meta:
        model = Group
        fields = ("id", "url", "name", "linked_sites")

    def validate_linked_sites(self, sites):
        ** code **
        return sites

    # noinspection PyMethodMayBeStatic
    def validate_name(self, name):
        ** code **
        return name

看法:

def patch(self, request, group_pk):
    """
    Add site to group, change an existing group's name.

        -id: The group's id
    """
    user = request.user
    group_id = int(group_pk)
    group = Group.objects.filter(pk=group_id).first()

    # Update the group
    serializer_class = self.get_serializer_class()
    serializer = serializer_class(
        data=self.request.data,
        context={"request": request, "user_pk": user.id, "group_id": group_id},
    )

測試類:

def test_ok_authorized_access(self):
    # Login the user
    self.client.force_login(self.user_1)
    UserSiteFactory(user=self.user_1, site=self.test_site_3)

    # Get the url
    url = reverse("group-detail", kwargs={"group_pk": self.test_group_1.pk})

    # New group name
    new_name = "New group name"

    sites = [self.test_site_3.pk]

    # Execute the patch operation
    response = self.client.patch(
        url, data={"name": new_name, "linked_sites": sites}
    )

    # Test if there was no error
    self.assertEqual(response.status_code, status.HTTP_200_OK)

    # Test if the group was renamed
    group = Group.objects.all().filter(pk=self.test_group_1.pk).first()
    self.assertEqual(group.name, new_name)

堆棧跟蹤

Traceback (most recent call last):
  File "/opt/project/backend/groups/tests/test_group_patch.py", line 45, in test_ok_authorized_access
    url, data={"name": new_name, "linked_sites": sites}
  File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 310, in patch
    path, data=data, format=format, content_type=content_type, **extra)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 215, in patch
    return self.generic('PATCH', path, data, content_type, **extra)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 232, in generic
    method, path, data, content_type, secure, **extra)
  File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 422, in generic
    return self.request(**r)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 283, in request
    return super().request(**kwargs)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/test.py", line 235, in request
    request = super().request(**kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/test/client.py", line 503, in request
    raise exc_value
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
    raise exc
  File "/usr/local/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "/opt/project/backend/groups/views/group_detail_view.py", line 108, in patch
    return Response(serializer.data, status=status.HTTP_200_OK)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 559, in data
    ret = super().data
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 263, in data
    self._data = self.to_representation(self.validated_data)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py", line 526, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 393, in to_representation
    url = self.get_url(value, self.view_name, request, format)
  File "/usr/local/lib/python3.6/site-packages/rest_framework/relations.py", line 329, in get_url
    lookup_value = getattr(obj, self.lookup_field)
AttributeError: 'collections.OrderedDict' object has no attribute 'pk'

來自HyperlinkedIdentityField 上的 DRF 文檔

lookup_field - 目標上應該用於查找的字段。 應對應於引用視圖上的 URL 關鍵字參數。 默認值為“pk”。

lookup_url_kwarg - 在 URL conf 中定義的與查找字段相對應的關鍵字參數的名稱。 默認使用與lookup_field相同的值。

所以你直接設置lookup_url_kwarg ,但你沒有改變lookup_field ,這是你的錯誤的來源。 因為lookup_url_kwarg默認值與lookup_field相同,所以我們可以使用它:

class GroupPatchSerializer(serializers.ModelSerializer):
    # code...
    url = serializers.HyperlinkedIdentityField(
        view_name="group-detail", lookup_field="group_pk"
    )
    # code...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM