DRF中从URL kwargs获取外键关联对象列表的规范实现咨询
现有实现的合理性
你的当前实现完全符合DRF设计规范,属于非常标准的嵌套资源查询写法,逻辑正确、可读性高,直接在线上环境使用没有任何问题。
基于DRF原生能力的优化实现
你提到的lookup相关参数的原生实现方案是存在的,这里给两种常用的符合DRF原生设计风格的实现方式:
方案1:结合过滤组件+lookup参数实现(无额外依赖)
可以通过DRF原生的过滤能力,配合lookup字段映射实现,不需要额外重写get_queryset的核心逻辑:
class CategoriesListView(ListAPIView): permission_classes = (IsAuthenticated,) serializer_class = CategorySerializer queryset = Category.objects.all() # 指定关联外键字段作为lookup匹配字段 lookup_field = 'store_id' lookup_url_kwarg = 'pk' def get_queryset(self): filter_kwargs = {self.lookup_field: self.kwargs[self.lookup_url_kwarg]} return super().get_queryset().filter(**filter_kwargs)
如果后续需要调整url参数名、或者关联字段名,只需要修改lookup_field和lookup_url_kwarg两个参数即可,不用改逻辑代码,可维护性更高。
方案2:搭配django-filter实现(官方推荐的可扩展方案)
如果你的项目已经引入了DRF官方推荐的django-filter过滤扩展,可以实现完全不用重写get_queryset方法:
from django_filters.rest_framework import DjangoFilterBackend class CategoriesListView(ListAPIView): permission_classes = (IsAuthenticated,) serializer_class = CategorySerializer queryset = Category.objects.all() filter_backends = (DjangoFilterBackend,) # 指定外键字段为过滤字段,和url里的pk参数做映射 filterset_fields = {'store_id': ['exact']} def get_filterset_kwargs(self, filterset_class): kwargs = super().get_filterset_kwargs(filterset_class) kwargs['data']['store_id'] = self.kwargs['pk'] return kwargs
这种方案的优势是后续如果要新增其他过滤条件,直接在filterset_fields里添加字段即可,扩展性极强。
方案选择建议
- 如果项目里这类嵌套资源接口数量少,你原有写法就足够高效,没有必要额外调整
- 如果项目内嵌套资源接口多,或者需要支持多维度过滤,推荐用第二种方案,更符合DRF的分层设计规范
内容的提问来源于stack exchange,提问作者Roman Shirokov
相关产品推荐
相关产品推荐

