我尝试了尽可能多的搜索答案,但我仍然不知道如何在这里实现目标。
我的目标: 我需要两个api端点,一个返回使用查找字段过滤的列表,另一个返回使用另一个字段过滤的obj,都使用GET方法。例如:
<ip>/api/books/bycategory/{category_lookup}/
此终结点将返回按类别过滤的书籍列表
<ip>/api/books/byid/{id_lookup}/
这将返回与指定ID(不是pk)匹配的一本书
由于这里没有适合我需要的内置路由器,因为内置路由器不提供带有返回列表的查找的url模式,因此我认为我需要拥有自己的自定义路由器,因此我所拥有的:
class CustomRouter(routers.SimpleRouter):
routes = [
routers.DynamicRoute(
url=r'^{prefix}/{url_path}/{lookup}{trailing_slash}$',
name='{basename}-{url_name}',
detail=True,
initkwargs={}
)
]
router = CustomRouter()
router.register('books', BookViewSet)
和我的序列化器:
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = BookKeeper
fields = '__all__'
直到现在,我认为我都处于正确的轨道上,但是当涉及到视图时,那是我无法弄清楚的地方。现在,我只有一个不完整的视图集:
class BookViewSet(viewsets.ReadOnlyModelViewSet):
queryset = BookKeeper.objects.all()
serializer_class = BookSerializer
@action(detail=True)
def bycategory(self, request):
lookup_field = 'category'
@action(detail=True)
def byid(self, request):
lookup_field = 'id'
我的第一个问题是,我在路由器URL中“认为” {url_path}
与方法名与在视图集中指定的@action
匹配,以及它们如何连接,对吗?
第二个问题是如何在视图中使用{lookup}值?
第三,如果我像这样使用lookup_field
是什么?
def bycategory(self, request):
return Response(BookKeeper.objects.filter(category=<lookup_value>))
最后我的视野应该是什么样的?
任何输入都会受到赞赏。
答案 0 :(得分:1)
第二个问题是如何在视图中使用{lookup}值?
对于同一组,您需要两个lookup_fields。您可以通过自定义的Mixin类来实现。但是在四种情况下,最好不要使用路由器,而要使用自定义网址,因此请按以下方式进行编辑:
# views.py
class BookViewSet(viewsets.ReadOnlyModelViewSet):
queryset = BookKeeper.objects.all()
serializer_class = BookSerializer
@action(detail=True)
def bycategory(self, request, category):
# do filtering by category
print(category)
@action(detail=True)
def byid(self, request, book_id):
# do filtering by book_id
print(book_id)
# urls.py
get_by_id = views.BookViewSet.as_view(
{
'get': 'byid'
}
)
get_by_category = views.BookViewSet.as_view(
{
'get': 'bycategory'
}
)
urlpatterns += [
url(
r'^api/books/byid/(?P<book_id>[0-9a-f-]+)/',
get_by_id,
name='get-by-id'
),url(
r'^api/books/bycategory/(?P<category>[0-9a-f-]+)/',
get_by_category,
name='get-by-category'
)
]