我想在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_name
的DefaultRouter
,但是我找不到如何从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/