ModelViewSet使用多lookup字段替换默认pk slug实现自定义无多余后缀URL
实现方案
你不需要修改ModelViewSet基类,按照以下步骤调整配置即可:
1. 调整路由配置
直接给DefaultRouter注册空前缀干掉多余的路径段,外层路由直接写你需要的两个slug参数:
from rest_framework.routers import DefaultRouter from .views import DeviceActivityModelViewSet router = DefaultRouter() # 注册空前缀,移除多余的organization路径段 router.register(r'', DeviceActivityModelViewSet, basename='device_activity') urlpatterns = [ # 直接声明两个需要的slug参数,不要多余前缀 path('<str:device>/<str:start_time>/', include(router.urls)) ]
2. 调整视图配置
同时保留lookup_fields和lookup_field两个配置:
lookup_fields给MultipleFieldLookupMixin做多字段匹配用lookup_field给DefaultRouter生成路由规则用,选两个slug中的任意一个即可
class DeviceActivityModelViewSet(MultipleFieldLookupMixin, viewsets.ModelViewSet): queryset = DeviceActivity.objects.all() serializer_class = DeviceActivitySerializer # 多字段查询用配置 lookup_fields = ["device", "start_time"] # 路由生成用配置 lookup_field = "start_time"
3. 调整序列化器配置
保持你之前的extra_kwargs配置,保证序列化器生成的url字段匹配路由规则:
class DeviceActivitySerializer(serializers.ModelSerializer): class Meta: model = DeviceActivity fields = "__all__" extra_kwargs = { 'url': {'lookup_field': 'start_time'} }
原理说明
Django路由include的外层参数会自动传递给内层视图的kwargs属性,MultipleFieldLookupMixin会遍历lookup_fields从kwargs中读取所有对应参数做过滤,不会受lookup_field单字段配置的影响。最终生成的接口端点完全符合你要求的mydomain.com/<str:device>/<str:start_time>/格式,同时支持两个slug的多字段查询。
内容的提问来源于stack exchange,提问作者Muhammad Naufil
相关产品推荐
相关产品推荐

