Django ReadOnlyModelViewSet:get_querySet 被 pk 过滤
Posted
技术标签:
【中文标题】Django ReadOnlyModelViewSet:get_querySet 被 pk 过滤【英文标题】:Django ReadOnlyModelViewSet: get_querySet getting filtered by pk 【发布时间】:2016-08-13 19:07:30 【问题描述】:我有一个端点,我想使用 url kwargs 过滤并返回一个查询集,如下所示:/api/myendpoint/id/ 应该返回所有 myendpoint 对象,其字段 X 与 id 匹配。我在我的视图类中提供了 get_query_set 方法,它是一个 ReadOnlyModelViewSet,它返回一个包含所有符合条件的对象的查询集(我知道这部分有效,因为我在返回结果之前打印出结果,它看起来是正确的)。
我似乎遇到的问题是 get_queryset 返回的查询集似乎在显示在端点上之前再次被 django 过滤。它被过滤为 pk==id。这不是我想要的功能,因为我使用 id 来过滤不同的字段。似乎它被视为 DetailView,但我希望它被视为集合视图(如果存在这样的事情)。如何在仍然使用 url kwargs 的同时为此视图返回多个对象?我是 django 初学者,如果这很明显,请见谅。
urls.py:
from rest_framework_nested_import routers
router = routers.DefaultRouter()
router.register(r'', MyView, base_name='myendpoint')
urlpatterns = patterns('',
url(r'^', include(router.urls)))
views.py:
class MyView(viewsets.ReadOnlyModelViewSet):
def get_queryset(self):
if 'pk' in self.kwargs:
return MyObj.objects.filter(field=self.kwargs['pk'])
【问题讨论】:
【参考方案1】:要返回集合,您不应传入 /pk/
,因为这将尝试获取具有该 ID 的单个对象,您已经看到了。
用于获取对象列表的正确 URL 是 /api/myendpoint/
。您可以使用queryset
属性或get_queryset
函数过滤对象列表。但是,我们仍然需要让 django 知道要过滤的字段和值。
这就是 filtering by query parameter 的用武之地。您也可以过滤 URL 字符串,但这有点复杂,因为您需要修改路由器 URL。
class MyView(viewsets.ReadOnlyModelViewSet):
def get_queryset(self):
queryset = MyObj.objects.all()
filter_value = self.request.query_params.get('field_name', None)
if filter_value is not None:
queryset = queryset.filter(field_name=filter_value)
return queryset
使用此代码,您可以点击/api/myendpoint/?field_name=somevalue
,它将返回 MyObj 模型过滤字段名的查询集。
【讨论】:
谢谢!那么,没有办法返回带有 /api/myendpoint/pk/ 端点的对象列表吗?我必须使用查询参数吗?这使得使用 api 稍微不那么直观... 你可以,但这将是对 ID 为pk
detail_route 的对象执行的操作。您想要做的是在 list_route django-rest-framework.org/api-guide/viewsets/… 上如果您需要过滤 url 本身而不是查询参数,您当然可以,但您需要将 url 路由从生成的默认值更改为ViewSet
django-rest-framework.org/api-guide/filtering/…以上是关于Django ReadOnlyModelViewSet:get_querySet 被 pk 过滤的主要内容,如果未能解决你的问题,请参考以下文章