首页 > 解决方案 > 将动态参数传递给 urlpatterns 或 DefaultRouter

问题描述

我有几个类别要在 rest_framework 中创建不同的视图。但所有类别都来自同一个模型。

令我震惊的是,这些类别可以urlpatterns作为关键字传递(或通过 访问DefaultRouter)。然后您可以根据需要使用关键字过滤模型。

这是我的看法:

class CategoryRankedViewSet(ModelViewSet):
    serializer_class = CategoriesSerializer

    def get_queryset(self):
        return Categories.objects.all().order_by(self.kwargs['category'])

我能够完成这项工作的一种方法是:

urlpatterns = [path('<' + category + '>/', CategoryRankedViewSet.as_view({'get': 'list'}), name=category) for category in CATEGORIES]

但这并不完美,因为参数的键设置为第一项的值 in CATEGORIES,而不是更通用的术语,如category.

我正在考虑DefaultRouter,但参数是否可以传递给DefaultRouter.

我还在寻找可以访问文字 url 并以这种方式访问​​类别的方法。在 DRF 中的 ViewSet 中不会出现这种情况。

此外,base_nameforDefaultRouter可以动态设置,但我找不到如何base_name从 ViewSet 访问。

有没有人试过这个,有没有更有效的方法?

UPDATE 事实证明,path()具有kwargs传递关键字的属性,而不会将它们作为 url 参数包含在内。所以不要将类别作为 url 参数传递。只需在 url 路径中使用 category 变量并将 category 作为关键字传递即可。

urlpatterns = [path(category + '/', CategoryRankedViewSet.as_view({'get': 'list'}), kwargs={'category': category}, name=category) for category in CATEGORIES]

有什么方法可以使用DefaultRouter???

标签: pythondjangodjango-rest-framework

解决方案


视图集可以通过使用@action装饰器装饰方法来标记路由的额外操作。您可以使用动作装饰器来解决您的问题

from rest_framework.decorators import action

class CategoryRankedViewSet(ModelViewSet):
    serializer_class = CategoriesSerializer

    def get_queryset(self):
        return Categories.objects.all().order_by(self.kwargs['category'])

    @action(methods=['get'],detail=False,url_path=r'list/(?P<category>[\w-]+)',url_name='categorylist')
    def get_category(self,request,category=None):
        return Categories.objects.all().order_by(category)

所以,现在您可以在 url 中提供任何类别并使用类别变量访问它。您的网址将类似于rooturl/list/{categoryhere} 。此网址将调用get_category方法。记住url_path只使用正则表达式,所以你不能在那里使用 slug。您可以在此链接中看到动作装饰器的代码,您可以在djagorest中看到 @action 装饰器的示例。我希望这能解决你的问题。


推荐阅读