当URL参数更改时,Django REST返回404

时间:2017-09-20 14:13:51

标签: python json django rest csv

我正在使用Django REST框架来创建支持JSON和CSV输出的API。

我在 $count = 8; for($i=1; $i<=$count; $i++) { $oddEven = ($i%2) ? "green" : "yellow"; echo "<div style='background-color:{$oddEven}'>{$i}</div>"; }

中有这一行

urls.py

EventsView看起来像这样:

url(r'^api/events/$', views.EventsView.as_view(), name='events'),

如果我访问class EventsView(APIView): def dispatch(self, request, *args, **kwargs): return super(EventsView, self).dispatch(request, *args, **kwargs) def get(self, request): logger.info("Here") events = EventsQuery(request) if events.is_valid(): events.build_response() return events.get_response() ,我会得到一组结果作为有效的JSON,,我看到“此处”已记录到我的日志文件

如果我访问/api/events/?format=json,我会收到一封带有JSON正文

的404回复
/api/events/?format=csv

... 没有记录任何内容

缺少伐木是什么让我失望。它就像它甚至没有进入EventsView类,但是如何更改URL中的查询字符串值会阻止它被路由到该类?我如何找出它被路由到哪里?

编辑:EventsQuery.get_response()的内容是:

{
"detail": "Not found."
}

2 个答案:

答案 0 :(得分:0)

我仍然不清楚根本原因,但我通过使用format_suffix_patterns传递format参数来解决这个问题,而不是将其作为查询字符串参数传递。我确认 - 通过重写APIView.handle_exception() - 父类引发了404异常,但我不知道为什么。

答案 1 :(得分:0)

我刚刚遇到这个问题并深入了解它。

根本原因是,在 DRF 中,'format' url 参数用于确定在内容协商阶段使用哪个渲染器类,如果没有一个渲染器类具有匹配的格式属性,则内容协商器返回 404格式 url 查询参数。查看 rest_framework.negotiation.DefaultContentNegotiation.filter_renderers method 中的代码。

其他人在 DRF 数据表存储库中遇到了这个问题 - https://github.com/izimobil/django-rest-framework-datatables/issues/4

为了后人重复我在那里发布的内容 - 您可以(至少)通过两种方式解决这个问题。最可靠的方法是创建您自己的内容协商类,该类在过滤渲染器时遵循不同的登录名。出于我的目的,我只想使用 format kwarg 来确定在视图集中使用哪个序列化器类,我很高兴通过创建一个具有我想要的格式属性的虚拟渲染器类来解决这个问题采用。举个例子:

from rest_framework.renderers import JSONRenderer

class GeoJsonRenderer(JSONRenderer):
    format = "geojson"

class MyViewSet(ModelPermissionsMixin, ModelViewSet):
    def get_renderers(self):
        return super().get_renderers() + [GeoJsonRenderer()]

    def get_serializer_class(self):
        format = self.request.query_params.get("format")
        if format and format == "geojson":
            return GeoJsonSerialiser
        return super().get_serializer_class()