如何在Django REST Framework的ViewSet中根据URL路径slug获取单个产品对象
修复方案
DRF的ModelViewSet默认使用主键pk作为单对象查询的匹配字段,仅需修改lookup_field属性即可实现基于slug的查询,无需额外定义单独的详情视图集。你现有代码的三处核心错误如下:
- 类定义语法错误:
class ProductDetailViewSet(viewsets.ViewSet, slug):父类声明位置不能传递参数slug - 路由配置不完整:
path('<str:slug>/',)未绑定对应的视图处理逻辑 - 拼写错误:视图中定义的类名为
ProductDetailViewSet,路由文件导入时错误写为ProductDetailiewSet
最优修改方案(适配全量接口用slug作为标识)
1. 修正 product/views.py
from rest_framework import viewsets from .serializers import ProductSerializer from .models import Product class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all().order_by('name') serializer_class = ProductSerializer # 新增该行指定slug为查询字段 lookup_field = 'slug'
2. 修正 product/urls.py
修改lookup_field后,路由组件会自动生成带slug参数的详情接口,无需额外手动配置路径:
from rest_framework import routers from django.urls import path, include from .views import ProductViewSet router = routers.DefaultRouter() router.register(r'', ProductViewSet) urlpatterns = [ path('', include(router.urls)) ]
配置完成后,直接访问/<slug>/即可获取对应产品的详情数据,增删改查所有接口都会自动适配slug作为对象标识。
备选方案(保留主键作为默认标识,新增单独的slug查询接口)
如果不需要修改全量接口的默认匹配规则,仅需要单独的slug查询接口,可以在原有ProductViewSet中添加自定义action:
from rest_framework import viewsets from rest_framework.decorators import action from rest_framework.response import Response from django.shortcuts import get_object_or_404 from .serializers import ProductSerializer from .models import Product class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all().order_by('name') serializer_class = ProductSerializer @action(detail=False, methods=['get'], url_path='get-by-slug/(?P<slug>[-\w]+)') def get_by_slug(self, request, slug=None): product = get_object_or_404(Product, slug=slug) serializer = self.get_serializer(product) return Response(serializer.data)
该方案下原有基于主键的接口保持不变,新增/get-by-slug/<slug>/接口用于通过slug查询产品。
内容的提问来源于stack exchange,提问作者mateuszlaczynski
相关产品推荐
相关产品推荐

