【问题标题】:Django REST Framework -- destroy method won't take on URL params?Django REST Framework -- destroy 方法不会使用 URL 参数?
【发布时间】:2016-10-11 11:01:46
【问题描述】:

我正在使用 Django REST Framework 设计一个 API 端点,并希望它在以下端点接受 GET 和 POST 方法:

companies/<company_pk>/membership

以及以下端点的 DELETE 方法:

companies/<company_pk>/membership/<membership_pk>

有两个相关模型:CompanyCompanyMembership。每个用户可以是一个或多个公司的成员,由CompanyMembership 的一个实例表示,该实例通过FK 链接到Company

我已经创建了适当的 GET 和 POST 请求,但在处理 DELETE 请求时遇到了问题——我的视图中的 destroy 方法似乎缺少 membership_pk 参数,无论我是否在其中定义它我的网址。如何让我的视图接受删除 CompanyMembership 实例的 DELETE 请求,这些实例由 URL 中给出的 membership_pk 标识?

urls.py

...
    url(r'^companies/(?P<company_pk>[0-9]+)/membership', include(company_urls.company_membership_router.urls,
        namespace='company_memberships')),
...

views.py


class CompanyMembershipViewSet(viewsets.ModelViewSet):
    """
    A ViewSet for creating, retrieving, and deleting CompanyMemberships.
    """
    queryset = CompanyMembership.objects.all()
    serializer_class = CompanyMembershipSerializer
    lookup_url_kwarg = 'company_pk'

    def get_queryset(self):
        uid = self.kwargs.get(self.lookup_url_kwarg)
        memberships = CompanyMembership.objects.filter(company_id=uid)
        return memberships

    def create(self, request, company_pk):
        """
        Custom create method since company_pk does not have to be sent
        explicitly within request.data

        Returns: instance of rest_framework Response.
        """
        EXISTING_USER_ERROR = {'non_field_errors':
            ['The fields user, company must make a unique set.']
        }
        data = {
            'user': request.data['user'],
            'company': company_pk
        }
        serializer = CompanyMembershipSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        if serializer.errors == EXISTING_USER_ERROR:
            return Response(serializer.errors, status=settings.ADDITIONAL_HTTP_STATUS_CODES['422_UNPROCESSABLE_ENTITY'])
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def destroy(self, request, **kwargs):
        company_membership = self.get_object(pk=membership_pk)
        company_membership.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


routers.py
    from rest_framework import routers

    from .views import CompanyViewSet, CompanyMembershipViewSet


    company_router = routers.DefaultRouter()
    company_membership_router = routers.DefaultRouter()

    company_router.register(r'^', CompanyViewSet)
    company_membership_router.register(r'^', CompanyMembershipViewSet)

【问题讨论】:

  • 你的 membership_pk 在你的销毁方法中定义在哪里?你是说kwargs['membership_pk']
  • @dnit13 是的,这正是我的问题——当我添加一个 break 语句并在 kwargs 中查找 destroy 方法时,没有 membership_pk,即使我发送的 URL 是POST 请求是 companies/10/membership/3 - 所以显然有一个 membership_pk 应该以某种方式传递 - 我只是不确定为什么 destroy 方法无法访问它。我怀疑我的 URL 设置有误?

标签: python django rest python-3.x django-rest-framework


【解决方案1】:

公司会员路由器生成以下网址:

companies/<company_pk>/membership/ # for handling list requests
companies/<company_pk>/membership/<pk>/ # for handling detail requests

您可以使用pk url kwarg 访问membership_pk

另外,您在视图集中错误地定义了lookup_url_kwarg 字段。这个kwarg 被DRF 用来使用get_object() 方法检索对象。您没有得到对象,因为它试图使用pk 作为company_pk url kwarg 值而不是pk 值执行查找。

【讨论】:

  • 谢谢。设法通过删除lookup_url_kwarg 并使用Membership.objects.get(pk=self.kwargs.get('pk')) 查找对象来查找它
猜你喜欢
  • 2020-06-07
  • 1970-01-01
  • 2022-08-18
  • 2017-01-09
  • 1970-01-01
  • 2019-02-12
  • 2013-08-05
  • 1970-01-01
  • 2021-06-19
相关资源
最近更新 更多