2017-10-04 64 views
0

我有一個返回JsonResponse的視圖。我想使用Building實例(結構變量)生成pdf報告。Django - 使用相同的類實例返回Pdf和JsonResponse

例如,返回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意味着一個新的建築實例。除此之外,還有另一種解決方案使用另一種視圖解決問題。

在前端,我想顯示JsonResponse並讓用戶可以使用pdf下載使用HTML按鈕。

使用芹菜適合這項任務嗎?

提前致謝!

回答

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) 

現在,關於使用芹菜:當你知道任務是要霸佔機器很長一段時間,如創建一個沉重的PDF,最好採取這些任務退出響應fl流。這就造成了很多你需要找出其他的問題,但它會是這個樣子:

  1. 接收請求創建一個PDF
  2. 創建芹菜任務和保存某種狀態一個模型或某個地方。
  3. 發送一個回覆,指出正在創建PDF。
  4. 開始輪詢任務的狀態...
  5. 芹菜任務完成後,更改模型的狀態或其他。
  6. 停止輪詢並通知用戶文件已準備好下載。
  7. 讓用戶以某種方式進行下載,最好是使用按鈕,因爲任何類型的下載都不是用戶交互的產品,因此被許多瀏覽器視爲攻擊。

如果您的機器不能勝任,或者您的用戶負載太大,您在請求超時之前無法生成PDF,那麼您應該使用Celery,但很多PDF可以快速生成並且簡單。

+0

感謝您的回覆。我對答案的第一部分有疑問。代碼可以選擇生成pdf或html。如果我調用html的視圖函數,然後調用pdf,則該類會被調用兩次並生成兩次結果? 這就是結果在瀏覽器中顯示的方式。 [結果](https://i.imgur.com/WV6fU07.png) – Eduardo

+0

關於答案的第二部分我將調查芹菜的使用。我現在可以在視圖中延遲任務,但是如何在以後使用圖像中顯示的按鈕調用,從url引用其他視圖? – Eduardo

+0

-first:如果您向視圖發送兩個請求,該視圖將生成兩個響應,HTTP是一個無狀態協議,您有責任緩存您希望在兩個響應之間共享的任何中間結果。 -second:您可能需要編寫另一個視圖來檢查狀態(這將輸出任務的狀態),另一個視圖請求文件,這將處理Content-Disposition標頭以下載文件,這些視圖完全相同完全不同的問題。 – fixmycode

相關問題