我有一个标准的DRF Web应用程序,可为其中一条路线输出CSV数据。渲染整个CSV表示需要花费一些时间。数据集非常大,所以我希望有一个HTTP流响应,这样客户端就不会超时。

但是,使用https://github.com/mjumbewu/django-rest-framework-csv/blob/2ff49cff4b81827f3f450fd7d56827c9671c5140/rest_framework_csv/renderers.py#L197中提供的示例并不能完全做到这一点。数据仍然是一个较大的有效负载,而不是分块,并且客户端最终在接收字节之前等待响应。

结构类似于以下内容:

models.py

class Report(models.Model):
  count = models.PostiveIntegerField(blank=True)
  ...

renderers.py
class ReportCSVRenderer(CSVStreamingRenderer):
  header = ['count']

serializers.py
class ReportSerializer(serializers.ModelSerializer):
  count = fields.IntegerField()

  class Meta:
    model = Report

views.py
class ReportCSVView(generics.Viewset, mixins.ListModelMixin):
  def get_queryset(self):
    return Report.objects.all()

  def list(self, request, *args, **kwargs):
    queryset = self.get_queryset()
    data = ReportSerializer(queryset, many=True)
    renderer = ReportCSVRenderer()

    response = StreamingHttpResponse(renderer.render(data), content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="f.csv"'

    return response

注意:必须注释掉或更改某些内容。

谢谢

最佳答案

对于较小的响应,Django的StreamingHttpResponse可能比传统的HttpResponse慢得多。

如果不需要,请不要使用它; Django Docs实际上建议仅在绝对需要在将数据传输到客户端之前不对整个内容进行迭代的情况下才使用StreamingHttpResponse。”

同样对于您的问题,您可能会发现有用的设置chunk_size,切换到FileResponse或返回到正常的Response(如果使用REST框架)或HttpResponse。

编辑1:关于设置块大小:

File api中,您可以分块打开文件,因此并非所有文件都已加载到内存中。

希望这个对你有帮助。

10-01 02:37
查看更多