[英]'collections.OrderedDict' object has no attribute 'pk' - django rest framework
[英]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.