我想在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]


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

我正在考虑DefaultRouter,但是否可以将参数传递给DefaultRouter并不明显。

我也在寻找可以访问文字url的方式,并以此方式访问类别。似乎没有出现在DRF的ViewSet中。

另外,可以动态设置base_nameDefaultRouter,但是我找不到如何从ViewSet中访问base_name的方法。

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

更新
事实证明,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复制吗???

最佳答案

视图集可以通过使用@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中提供任何类别,并使用category变量进行访问。
您的网址将类似于rooturl / list / {categoryhere}。此网址将调用get_category方法。
请记住,url_path仅使用正则表达式,因此您不能在那里使用slug。
您可以在此link中查看动作装饰器的代码,并可以在djagorest中查看@action装饰器的示例。
我希望这能解决您的问题。

关于python - 将动态参数传递给urlpatterns或DefaultRouter,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57749288/

10-10 16:34