Django view html to pdf 执行了两次

Django view html to pdf executed twice

我按照 Class 生成 pdf 文件,我使用 django-renderpdf 从 html 模板生成 pdf。但是视图执行了两次并抛出错误。

我的class:

class WeeklyMetre(PDFView):
    template_name = 'reports/invoice/weekly_metre.html'

    allow_force_html = True
    prompt_download = True

    @property
    def download_name(self) -> str:
        invoice = Invoice.objects.get(pk=self.kwargs['pk'])
        return f"WeeklyMetre_{invoice.invoice_number}.pdf"

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        invoice = Invoice.objects.get(pk=self.kwargs.get('pk'))
        market_labor_specifications = _getWeeklyMetreData(invoice=invoice)

        # calculate reported items: reported market_labor_specifications
        # invoiced specifications which are validated in invoice-period
        # but labor_date before invoice-period

        reported_mls = MarketLaborSpecification.objects.filter(invoice_id=self.kwargs.get('pk'), market_labor__labor_date__lt=invoice.period_from) \
        .values('market_labor__labor_date', 'specification__position', 'specification__name') \
        .order_by('market_labor__labor_date', 'specification__position', 'specification__name') \
        .annotate(sum_pos=Sum('validated_quantity'))

        context.update({
            'invoice': invoice,
            'market_labor_specifications': market_labor_specifications,
            'reported_mlss': reported_mls
        })

        print('context data', datetime.datetime.now())
        return context

在两次执行之间出现以下错误:

[01/Feb/2021 07:16:38] "GET /reports/invoice/select/17/ HTTP/1.1" 200 1414
context data 2021-02-01 07:16:44.835695
[01/Feb/2021 07:16:45] "GET /reports/weekly/metre/17/ HTTP/1.1" 200 58063
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 60114)
Traceback (most recent call last):
  File "/usr/lib/python3.6/socketserver.py", line 654, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python3.6/socketserver.py", line 364, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python3.6/socketserver.py", line 724, in __init__
    self.handle()
  File "/home/t3tr4ktys/python-virtual-environments/BillOfQuantities/lib/python3.6/site-packages/django/core/servers/basehttp.py", line 174, in handle
    self.handle_one_request()
  File "/home/t3tr4ktys/python-virtual-environments/BillOfQuantities/lib/python3.6/site-packages/django/core/servers/basehttp.py", line 182, in handle_one_request
    self.raw_requestline = self.rfile.readline(65537)
  File "/usr/lib/python3.6/socket.py", line 586, in readinto
    return self._sock.recv_into(b)
ConnectionResetError: [Errno 104] Connection reset by peer
----------------------------------------
context data 2021-02-01 07:16:47.544189
[01/Feb/2021 07:16:48] "GET /reports/weekly/metre/17/ HTTP/1.1" 200 58063

首先我不知道为什么它被执行了两次并且在第二次执行时用户不再被认证。最后 pdf 生成良好,但我无法应用 LoginRequiredMixin。如果需要,将提供更多信息,感谢您的帮助。

我相信我经历过这样的事情。

问题是,当你调用你的端点时,你在 URL 中调用它,最后没有 '/' 导致 DRF return 301 将您重定向到相同的路径,但末尾带有“/”。这样做的问题是,在重定向之后您丢失了 headers 和 cookie,因此变得未经身份验证。

这也解释了为什么您可以看到 2 个调用。

所以基本上如果你有这样的电话:

api/viewset/dosomethngs

至:

api/viewset/dosomethngs/

看起来您在浏览器中关闭了标签页,或者浏览器停止以其他方式接受来自服务器的响应。但是网络服务器并没有停止它的渲染并且仍然生成响应,但是没有响应的对象。这就是为什么你会看到:

ConnectionResetError: [Errno 104] Connection reset by peer

浏览器重试页面重新加载后,您会在日志中看到第二个请求。

因此,您需要了解它发生的原因。查看浏览器日志,Dev.Tools 会向您显示(状态、响应等)。

P.S。关于 LoginRequiredMixin - 可能不知道浏览器的一些内部问题是由“重试”引起的,但我相信它仍然应该发送 cookie 和 session_id.