0

我正在通过传递参数在 DRF API 中创建删除方法,但我不知道如何正确传递 orientdb @rid。

我在 orientdb 中有一个名为“worksat”的关系,在 OrientDB Studio 中,我可以看到结构名称如#:的@rid ,即:“#33:1”是 workat 关系记录的@rid。

在此处输入图像描述

所以我需要在我的 DRF URL api 关系中传递该字符串:

http://127.0.0.1:8000/api/oworksat/

但是像这样传递:

http://127.0.0.1:8000/api/oworksat/#33:1

我看到 GET 请求,消息如下(我希望看到 DELETE): Allow: GET, POST, HEAD, OPTIONS

如果传递一个简单的数字:

http://127.0.0.1:8000/api/oworksat/1

然后我看到 DELETE 请求(显然“1”不存在):

HTTP 404 Not Found
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS

api.py:

class OWorksAtViewSet(viewsets.ModelViewSet):

    queryset = graph.oworksat.query()
    serializer_class = OWorksAtSerializer
    permission_classes = [
        permissions.AllowAny
    ]

    def destroy(self, request, *args, **kwargs):
        print ("destroy")
        import pdb;pdb.set_trace()

网址.py:

from django.conf.urls import include, url
from rest_framework import routers
from .api import (OWorksAtViewSet)
from rest_framework_swagger.views import get_swagger_view

router = routers.DefaultRouter()
router.register('api/oworksat', OWorksAtViewSet, 'oworksat')

schema_view = get_swagger_view(title='Swagger Documentation')

urlpatterns = [
    url(r'^swagger/$', schema_view)
]

urlpatterns += router.urls

有趣的是,通过从 swagger api 访问,在 DELETE 方法中,如果我传入请求“#33:1”的 ID,它会起作用,api 调用我的 destroy 方法并在 kwargs: 中接收kwargs = {'pk': '#33:1'}

在此处输入图像描述

我怎样才能从 DRF api 达到这种行为?

编辑: 这是我实现销毁方法的临时解决方案,但显然这只适用于 Swagger UI,通过在请求中传递 @rid。

from rest_framework import status
from rest_framework.response import Response
from core.pyorient_client import *

class OFriendsViewSet(viewsets.ModelViewSet):

    def destroy(self, request, *args, **kwargs):
        client = orientdbConnection()

        client.command("delete edge ofriends where @rid = '" + kwargs['pk'] + "'")

        return Response(status=status.HTTP_204_NO_CONTENT)
4

1 回答 1

1

我假设当谈到无法删除或看到“删除”按钮时,您谈论的是 Django Rest Framework 可浏览 API。

DRF 可浏览 API 的图片

例如,当您通过 DRF 可浏览 API 访问您的 API 时,您将获得对象列表http://127.0.0.1:8000/api/oworksat/。这是“列表端点”,它不支持DELETE.

当您访问单个对象的“详细端点”时,将出现删除按钮,例如:http://127.0.0.1:8000/api/oworksat/123.

但是,在您的情况下,当您尝试将 OrientDB@RID作为对象 ID 传递时,浏览器会认为您想要列出端点。这是因为在 urls 之后的所有内容#都称为片段,并且不会传递给服务器。因此,当您导航到http://127.0.0.1:8000/api/oworksat/#1:23浏览器实际请求页面时http://127.0.0.1:8000/api/oworksat/,从而为您提供没有删除按钮的列表端点。

为什么 Swagger 会起作用?

Swagger 之所以起作用,可能是因为发出请求的方式与浏览器通常加载页面的方式不同。当您单击“删除”按钮时,Swagger 会向您的 API 发出 Ajax 请求,因此片段部分不会从您的 url 中删除。Swagger 也可能 url 将您输入到 UI 中的值编码,这将转换#1:22%231%3A22并因此删除#导致我们的问题。然后 DRF 知道如何自动对 url 进行 url 解码并最终得到正确的 ID。

请求 Swagger 的示例可能会:

function deleteData(url, item) {
  return fetch(url + '/' + item, {
    method: 'DELETE',
    headers: {
      'Content-Type': 'application/json'
    }
  })
  .then(response => console.log(response.json()));
}

deleteData("http://127.0.0.1:8000/api/oworksat/", encodeURIComponent("#1:23"));

如何解决这个问题?

@RID当url 编码并发出 Ajax 请求时,您的 API 可能会正常工作。它只是不适用于 DRF 可浏览 API。

但是,为了更好地为您的用户工作,并使 DRF Browsable API 工作#,当它们通过您的 API 序列化时,我将从 ID 中删除。然后,用户会向诸如http://127.0.0.1:8000/api/oworksat/1:23. 当然,通过这样做,您需要在将客户端提供的 id#传递给 OrientDB 查询之前添加它。

于 2019-08-07T10:12:53.183 回答