簡體   English   中英

在Django rest框架中將orientdb @rid作為參數傳遞給DELETE請求的正確方法是什么?

[英]What is the correctly way to pass an orientdb @rid as a parameter, to DELETE request in django rest framework?

我正在通過傳遞參數在DRF API中創建一個delete方法,但是我不知道如何正確傳遞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()

urls.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實現該行為?

編輯:這是實現我的destroy方法的臨時解決方案,但顯然,這僅在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)

我假設在談論無法刪除或看到“刪除”按鈕時,您談論的是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 : http://127.0.0.1:8000/api/oworksat/123 : http://127.0.0.1:8000/api/oworksat/123

但是,對於您的情況,當您嘗試將OrientDB @RID傳遞為對象ID時,瀏覽器會認為您想列出端點。 這是因為在url中, #之后的所有內容都稱為fragment,並且此內容不會傳遞給服務器。 因此,當您導航至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也可能會將您輸入的值編碼到UI中,這會將#1:22轉換為%231%3A22 ,因此刪除#會導致我們的問題。 DRF然后知道如何對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正常工作,我將在ID通過ID序列化后從ID中刪除# 然后,用戶將向http://127.0.0.1:8000/api/oworksat/1:23網址發出請求。 當然,通過這樣做,您將需要在客戶端提供的ID之前加上#然后再將其傳遞給OrientDB查詢。

暫無
暫無

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

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