gpt4 book ai didi

python - @list_route 和@detail_route 嵌套路由不会出现在 Browseable API 中

转载 作者:太空宇宙 更新时间:2023-11-03 11:28:13 25 4
gpt4 key购买 nike

我正在尝试通过 @list_route@detail_route 装饰器使用嵌套路由。路线有效并返回数据,但我必须在地址栏中手动导航到它们。它们不会出现在可浏览 API 中的 DefaultRouter 生成的 ApiRoot 中。我正在使用 Django 1.8 和 Rest Framework 3.1.1。

urls.py 中:

router = DefaultRouter()
router.register(r'aggregates', viewsets.AggregateViewSet, base_name='aggregate')

urlpatterns = [
url(r'^api/', include(router.urls, namespace='myapp')),
]

viewsets.py中:

class AggregateViewSet(viewsets.GenericViewSet):
queryset = models.DataAggregate.objects.order_by('id')
serializer_class = serializers.AggregateSerializer

def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)

if page:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

@list_route(url_path='recent')
def recent_aggregates(self, request):
return Response({'message': 'herp a derp'})

当我导航到 /myapp/api 时,可浏览的 API 只显示:

HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, HEAD, OPTIONS

{
"aggregates": "http://localhost:8000/myapp/api/aggregates/"
}

期待这个:

{
"aggregates": "http://localhost:8000/myapp/api/aggregates/"
"aggregates-recent": "http://localhost:8000/myapp/api/aggregates/recent"
}

我尝试了各种修改版本,看它是否会让步,但无济于事。同样,这些路由确实起作用,并且如果我手动导航到它们,可浏览 API 将显示它们的页面……但违背了可浏览 API 的目的。

我看了一下 DefaultRouter(和 SimpleRouter)的代码,它似乎确实发现了动态路由...

最佳答案

这是真的,默认情况下它不会出现在 API 中。

我自己使用该代码段来提供嵌套路由,遵循 HAL样式(py3 代码)。

import urllib
from collections import OrderedDict

from rest_framework import serializers, relations

class SubNamespaceURLField(relations.HyperlinkedIdentityField):
"""Refers to a child namespace of the object, as pointed by view_name
"""
def __init__(self, namespace, *args, **kwargs):
self.namespace = namespace.strip('/')
super().__init__(*args, **kwargs)

def field_to_native(self, obj, field_name):
base = super().field_to_native(obj, field_name)
return urllib.parse.urljoin(base, self.namespace) + '/'

class HALNestedLinksField(relations.HyperlinkedIdentityField):
""" Tries to represent a list of nested links on the resource a
HAL-compliant way.

See http://stateless.co/hal_specification.html
"""
def __init__(self, endpoints, *args, **kwargs):
"""
:param endpoints list of url suffixes leading to nested operations on
the resource (ex: ['preview', 'check'])
"""
self.endpoints = endpoints
super().__init__(*args, **kwargs)

def get_attribute(self, obj):
return obj

def to_representation(self, value):
links = OrderedDict()
prefix = super().to_representation(self.get_attribute(value))
for i in self.endpoints:
# We consider if it contains a dot its a content-type indication,
# so no trailing slash
if '.' in i:
suffix = ''
else:
suffix = '/'
links[i] = {'href':
urllib.parse.urljoin(prefix, i) + suffix}
return links

然后在你的序列化器中使用它:

class SomeModelSerializer(serializers.HyperlinkedModelSerializer):
_links = HALNestedLinksField(['revalidate'], # you detail_route names
view_name='somemodel-detail')
class Meta:
model = SomeModel
fields = ('url',
'date',
'_links') # do not forget it

您将获得一个 _links 属性,其中包含您在 HALNestedLinksField 中声明的所有相关路由。

关于python - @list_route 和@detail_route 嵌套路由不会出现在 Browseable API 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29568477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com