Django - 使用相同的类实例

时间:2017-10-04 13:38:55

标签: python django

我有一个返回JsonResponse的视图。我想使用Building实例(结构变量)生成pdf报告。

例如,返回JsonResponse的视图是:

   @login_required
    def buildings(request):
        if request.POST and request.is_ajax():
            s_form = BuildingForm(request.POST)
            if s_form.is_valid():
                structure = Building(**s_form.cleaned_data)
                html = render_to_string('wind/results/buildings/buildings_results.html', {'structure': structure})
                return JsonResponse({"result": html})
            else:
                return JsonResponse({'building_errors': s_form.errors,
                                    status=400)
        else:
            s_form = BuildingForm()
            return render(request, 'wind/buildings.html', {'s_form': s_form})

我有以下代码用于生成并返回pdf:

    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="Report.pdf"'
    buffer = BytesIO()
    report = BuildingsReport(structure)  # I want to use the same Building instance
    pdf = report.generate_pdf()
    response.write(pdf)
    return response

我想要的是使用相同的构建实例来生成pdf和html变量。

使用不同的视图返回pdf意味着新的Building实例。除了有另一个解决方案使用另一个视图解决问题。

在前端我想要显示JsonResponse并使用pdf可供用户使用html按钮下载。

使用Celery可以完成这项任务吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

如果您想使用相同的视图发送两种不同的格式,那就完全没问题了,事实上,许多API会让您选择说明您想要接收的格式,例如:

/buildings?format=pdf

你可以用这样的视图解析它:

def buildings(request):
    format = request.GET.get('format', 'html').lower() # HTML is the default method
    if format is 'pdf':
        return create_PDF_response(request) # create your PDF
    elif format is 'json':
        return carry_on_with_JSON_response(request)
    return the_default_HTML_response(request)

现在,关于使用Celery:当您知道任务将长时间占用机器时,例如创建繁重的PDF,最好将这些任务从响应流中取出。这会产生很多其他问题,你需要弄清楚,但它看起来像这样:

  1. 接收创建PDF的请求
  2. 创建一个芹菜任务并在模型或某个地方保存某种状态。
  3. 发回一条回复,说明正在创建PDF。
  4. 开始轮询任务的状态......
  5. 完成芹菜任务后,更改模型的状态或其他任何内容。
  6. 停止轮询并通知用户该文件已准备好下载。
  7. 以某种方式让用户进行下载,最好使用按钮,因为任何不是用户交互产品的下载都会被许多浏览器视为攻击。
  8. 如果您的计算机无法满足要求,或者您的用户负载太大而无法在请求超时之前生成PDF,那么您应该使用Celery,但可以快速简单地生成许多PDF。 / p>