【问题标题】:How to send PUT request to ModelViewSet without passing a primary key in the url?如何在不在 url 中传递主键的情况下向 ModelViewSet 发送 PUT 请求?
【发布时间】:2021-07-24 03:25:07
【问题描述】:

我对使用ModelViewSet特别感兴趣 用于解决更新登录用户个人资料的挑战。我正在使用以下定义:

from rest_framework import viewsets

class ProfileRetrieveUpdate(viewsets.ModelViewSet):
    serializer_class = UserProfileSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]

    def get_queryset(self):
        return UserProfile.objects.filter(user=self.request.user)

    def perform_update(self, serializer):
        serializer.save(user=self.request.user)

通过覆盖get_queryset,我能够获得预期的行为,即当我访问端点时(比如profile/),我获得了登录用户的配置文件。但是,如果我必须更新配置文件,我只能通过转到 profile/6/ 来访问 PUT。有没有办法让ModelViewSet 在同一端点(即profile/)公开PUT

【问题讨论】:

标签: django-rest-framework django-rest-viewsets


【解决方案1】:

你可以在任何你想要的路径下注册ModelViewSetHTTP方法。

path(
    "profile",
    ProfileRetrieveUpdate.as_view(
        {"put": "partial_update", "get": "retrieve"}
    ),
    name="profile-retrieve-update",
)

您将不得不调整其他内容,以及您不提供pk。 您需要根据需要调整 get_object,而不是覆盖 get_queryset 方法。

from rest_framework import viewsets
from rest_framework.generics import get_object_or_404


class ProfileRetrieveUpdate(viewsets.ModelViewSet):
    serializer_class = UserProfileSerializer
    permission_classes = [permissions.IsAuthenticatedOrReadOnly]
    queryset = UserProfile.objects.all()

    def get_object(self):
        obj = get_object_or_404(self.queryset, user=self.request.user)
        self.check_object_permissions(self.request, obj)
        return obj

    def perform_update(self, serializer):
        serializer.save(user=self.request.user)

现在,如果您 PUT profile/ 它应该可以按预期工作。

【讨论】:

  • 嗯,我仍然可以在视图上正确获得Expected view ProfileRetrieveUpdate to be called with a URL keyword argument named "pk". Fix your URL conf, or set the .lookup_field` 属性。`
猜你喜欢
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
  • 2019-10-01
  • 1970-01-01
  • 2020-04-08
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多