【问题标题】:Django ReadOnlyModelViewSet: get_querySet getting filtered by pkDjango ReadOnlyModelViewSet:get_querySet 被 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'])

【问题讨论】:

    标签: django django-rest-framework


    【解决方案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 路由从生成的默认值更改为ViewSetdjango-rest-framework.org/api-guide/filtering/…
    猜你喜欢
    • 2018-01-21
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 2017-08-03
    • 2021-12-29
    相关资源
    最近更新 更多