如何构建一个从URL中提取多个参数的Django REST路由?

Saq*_*Ali 8 python django rest

我已经为我的应用程序构建了一些Django-Rest-Framework API.这些API执行诸如模型实例的返回列表以及有多少模型满足预定标准的返回计数之类的操作.

这是我的ViewSet的样子:

class MyObjectsViewSet(viewsets.ViewSet):

    def retrieve(self,request,pk=None):
        queryset = ## Do something here to return a list of myObjects
        serializer = MyObjectsSerializer(queryset) ## MyObjectsSerializer not shown here.
        return Response(serializer.data,status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)

这是我的urls.py对于这个端点的样子:

router = routers.DefaultRouter()
router.register(r'myObjects', views.myObjectsViewSet, base_name="myObjects")

urlpatterns = patterns('',
    ...
    url(r'^api/', include(router.urls)),
    ...
)
Run Code Online (Sandbox Code Playgroud)

上面的代码允许我将一个参数带到API并将其用作MyObjectsViewSet.retrieve()中的pk参数.因此,当我将浏览器指向/ api/MyObjects/60 /时,使用pk == 60调用retrieve().很棒.一切都很棒.

但现在我需要一个可以做更多事情的API.我需要一个带有两个数字参数("pk"和"otherArg")的API,并使用这两个参数调用另一个viewSet(MyObjectsNewView).因此,当我将浏览器指向/ api/MyObjects/60/59 /时,将使用参数pk == 60和otherArg == 59调用MyObjectsNewView.retrieve().

如何在url.py和我的Viewsets中设计我的路线以使其工作?

在其他情况下,当我设计非REST URL时,我使用了regexp并使用这样的符号来从URL字符串中指定提取参数:(?P<MyObjectID>\d+).

看起来我应该能够在这里做同样的事情.但是,它会自动接收pk参数而不在路由中的任何位置指定它,所以现在我很困惑如何在第一个pk参数sorta神奇地出现而没有任何正则表达式模式时如何向此路由添加另一个参数.

Pat*_*tti 6

编写自定义详细路由并更改签名以传递您打算使用的附加 kwarg。然后,自定义 url 路径。

from rest_framework.decorators import detail_route
from rest_framework import viewsets

class MyObjectsViewSet(viewsets.ViewSet):

    @detail_route(methods=['get'], url_path='(?P<oid>\d+)')
    def get_with_objectid(self,request,pk=None, oid=None):
        queryset = ## Do something here with oid to return a list of myObjects
        serializer = MyObjectsSerializer(queryset) ## MyObjectsSerializer not shown here.
        return Response(serializer.data,status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)

现在您的视图集将/api/MyObjects/60/59/在 pk=60 和 oid=59 的地方工作。如果 url_path 是,url_path='/thisthing/(?P(<oid>\d+)'则视图集将注册/api/MyObjects/60/thisthing/59


Ale*_*dri 3

您可以采用以下模式:

url(r'^resource/(?P<clientId>[A-Za-z0-9]*)/(?P<token>[A-Za-z0-9]*)$', RestResource.as_view()),
Run Code Online (Sandbox Code Playgroud)

RestResource 类看起来像这样:

class RestResource(View):
  def put(self, request, clientId, token):
    # Your code here
    return HttpResponse(json.dumps(JSON_DATA_VARIABLE), content_type = "application/json", status = 200)

  def delete(self, request, clientId, token):
    # Your code here
    return HttpResponse(json.dumps(JSON_DATA_VARIABLE), content_type = "application/json", status = 200)
Run Code Online (Sandbox Code Playgroud)

它将接受“PUT”和“DELETE”请求,并且路由中定义的参数将在类方法中接收。

希望对您有帮助,如果您需要的话,我可以为您提供更多详细信息。