【问题标题】:Why does Django REST Framework Router break query parameter filtering?为什么 Django REST Framework Router 会破坏查询参数过滤?
【发布时间】:2021-08-23 06:06:56
【问题描述】:

Django REST Framework Tutorial quickstart中,视图被添加到默认路由器:

// project/urls.py
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)

我的项目布局是

project/
    stuffs/

我在默认路由器中包含了 stuffs 应用程序:

router.register(r'stuffs', views.StuffViewSet)

stuffs/ 端点随后很好地列在端点的 API 根列表中:

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "users": "http://localhost:8000/users/",
    "groups": "http://localhost:8000/groups/",
    "stuffs": "http://localhost:8000/stuffs/"
}

Stuff 对象与所​​有者模型类有关系,为了过滤属于某个所有者的对象,我打算使用如下请求:

stuffs/?owner_id=abc

为了做到这一点,在这里我不确定它是否正确,我在stuffs 应用程序中引入了urls.py 配置:

// stuffs/urls.py
urlpatterns = format_suffix_patterns([
    path('stuffs/', stuffs_views.StuffList.as_view()),
    path('stuffs/<int:pk>/', stuffs_views.StuffDetail.as_view()),
    re_path(r'^stuffs/(?P<owner_id>.+)$', stuffs_views.StuffsList.as_view())
])

使用以下基于 StuffsList 类的视图:

class StuffList(generics.ListCreateAPIView):
    serializer_class = StuffSerializer
    def get_queryset(self):
        queryset = Stuff.objects.all()
        owner_id = self.request.query_params.get('owner_id')
        if owner_id is not None:
            queryset = queryset.filter(owner__owner_id=owner_id)
        return queryset

我很确定这个视图是正确的,因为当我从默认路由器中删除视图集时,查询会起作用。

但是,当视图集在默认路由器中注册时,当请求stuffs/?owner_id=abc 时,不应用过滤器。

我希望在端点列表中包含视图集,但同时能够使用查询参数进行过滤。我该怎么做?

【问题讨论】:

  • 可以分享StuffViewSet的实现吗?根据这一点,您可能需要覆盖 StuffViewSetlist 方法并将您的过滤器放在那里。

标签: django django-rest-framework django-rest-framework-filters


【解决方案1】:

您为什么要尝试使用 short_id ?无论如何试试这个:

def get_queryset(self):
    queryset = Stuff.objects.all()
    owner_id = self.request.query_params.get('owner_id')
    if owner_id is not None:
        queryset = queryset.filter(owner__short_id=int(owner_id))
    return queryset

【讨论】:

  • 应该到处都是owner_idshort_id 是原始代码的残骸),我更正了。
  • 没有r'^stuffs/(?P&lt;owner_id&gt;.+)$' 路由,过滤就不再起作用了。
猜你喜欢
  • 2018-07-28
  • 2016-01-14
  • 2011-07-17
  • 2020-09-25
  • 2019-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多