DRF如何返回通过自定义路由器和ModelViewSet进行查找而过滤的列表

时间:2019-07-12 09:13:38

标签: django-rest-framework

我尝试了尽可能多的搜索答案,但我仍然不知道如何在这里实现目标。

我的目标: 我需要两个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>))

最后我的视野应该是什么样的?

任何输入都会受到赞赏。

1 个答案:

答案 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'
    )
]