get_template_names(self) 在 TemplateView 中不起作用
get_template_names(self) doesn't work in TemplateView
我正在尝试使用 django-pdfkit
中的 PDFView
。问题是我没有一个模板。相反,我有 4 个模板。选择的模板取决于 request.GET 参数。
所以我创建了一个名为 Test 的 View
,它扩展了 PDFView
。
class Test(PDFView):
def get_template_names(self):
# don't bother with chosing template for now
return ["pdf/dobropis_pdf_template.html"]
def get_context_data(self, **kwargs):
doklad = get_object_or_404(Doklad, pk=self.request.GET.get('id'))
return {'doklad':doklad}
问题是,如果我不指定 template_name
,它 returns:
TemplateDoesNotExist at /render/doklad/ None
所以我想 get_template_names
方法甚至都没有被调用。
为什么会这样?我怎样才能让它发挥作用?
来自urls.py
:
url(r'^render/doklad/', views.Test.as_view(), name="doklad_to_pdf"),
这是 PDFView
(以防有帮助):
class PDFView(TemplateView):
#: Set to change the filename of the PDF.
filename = None
#: Set to default the PDF display to inline.
inline = False
#: Set pdfkit options dict.
pdfkit_options = None
def get(self, request, *args, **kwargs):
"""
Return a HTTPResponse either of a PDF file or HTML.
:rtype: HttpResponse
"""
if 'html' in request.GET:
# Output HTML
content = self.render_html(*args, **kwargs)
return HttpResponse(content)
else:
# Output PDF
content = self.render_pdf(*args, **kwargs)
response = HttpResponse(content, content_type='application/pdf')
if (not self.inline or 'download' in request.GET) and 'inline' not in request.GET:
response['Content-Disposition'] = 'attachment; filename=%s' % self.get_filename()
response['Content-Length'] = len(content)
return response
def render_pdf(self, *args, **kwargs):
"""
Render the PDF and returns as bytes.
:rtype: bytes
"""
html = self.render_html(*args, **kwargs)
options = self.get_pdfkit_options()
if 'debug' in self.request.GET and settings.DEBUG:
options['debug-javascript'] = 1
kwargs = {}
wkhtmltopdf_bin = os.environ.get('WKHTMLTOPDF_BIN')
if wkhtmltopdf_bin:
kwargs['configuration'] = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_bin)
pdf = pdfkit.from_string(html, False, options, **kwargs)
return pdf
def get_pdfkit_options(self):
"""
Returns ``self.pdfkit_options`` if set otherwise a default dict of options to supply to pdfkit.
:rtype: dict
"""
if self.pdfkit_options is not None:
return self.pdfkit_options
return {
'page-size': 'A4',
'encoding': 'UTF-8',
}
def get_filename(self):
"""
Return ``self.filename`` if set otherwise return the template basename with a ``.pdf`` extension.
:rtype: str
"""
if self.filename is None:
name = splitext(basename(self.template_name))[0]
return '{}.pdf'.format(name)
return self.filename
def render_html(self, *args, **kwargs):
"""
Renders the template.
:rtype: str
"""
static_url = '%s://%s%s' % (self.request.scheme, self.request.get_host(), settings.STATIC_URL)
media_url = '%s://%s%s' % (self.request.scheme, self.request.get_host(), settings.MEDIA_URL)
with override_settings(STATIC_URL=static_url, MEDIA_URL=media_url):
template = loader.get_template(self.template_name)
context = self.get_context_data(*args, **kwargs)
html = template.render(context)
return html
通过覆盖 get
,您已绕过 所有 该视图的内置功能,包括 get_template_names
的调用。这很少是正确的做法。
但是,鉴于您显示的代码,您不能从 render_html
中自己调用该方法的原因是什么?或者只是在那里内联逻辑。
我正在尝试使用 django-pdfkit
中的 PDFView
。问题是我没有一个模板。相反,我有 4 个模板。选择的模板取决于 request.GET 参数。
所以我创建了一个名为 Test 的 View
,它扩展了 PDFView
。
class Test(PDFView):
def get_template_names(self):
# don't bother with chosing template for now
return ["pdf/dobropis_pdf_template.html"]
def get_context_data(self, **kwargs):
doklad = get_object_or_404(Doklad, pk=self.request.GET.get('id'))
return {'doklad':doklad}
问题是,如果我不指定 template_name
,它 returns:
TemplateDoesNotExist at /render/doklad/ None
所以我想 get_template_names
方法甚至都没有被调用。
为什么会这样?我怎样才能让它发挥作用?
来自urls.py
:
url(r'^render/doklad/', views.Test.as_view(), name="doklad_to_pdf"),
这是 PDFView
(以防有帮助):
class PDFView(TemplateView):
#: Set to change the filename of the PDF.
filename = None
#: Set to default the PDF display to inline.
inline = False
#: Set pdfkit options dict.
pdfkit_options = None
def get(self, request, *args, **kwargs):
"""
Return a HTTPResponse either of a PDF file or HTML.
:rtype: HttpResponse
"""
if 'html' in request.GET:
# Output HTML
content = self.render_html(*args, **kwargs)
return HttpResponse(content)
else:
# Output PDF
content = self.render_pdf(*args, **kwargs)
response = HttpResponse(content, content_type='application/pdf')
if (not self.inline or 'download' in request.GET) and 'inline' not in request.GET:
response['Content-Disposition'] = 'attachment; filename=%s' % self.get_filename()
response['Content-Length'] = len(content)
return response
def render_pdf(self, *args, **kwargs):
"""
Render the PDF and returns as bytes.
:rtype: bytes
"""
html = self.render_html(*args, **kwargs)
options = self.get_pdfkit_options()
if 'debug' in self.request.GET and settings.DEBUG:
options['debug-javascript'] = 1
kwargs = {}
wkhtmltopdf_bin = os.environ.get('WKHTMLTOPDF_BIN')
if wkhtmltopdf_bin:
kwargs['configuration'] = pdfkit.configuration(wkhtmltopdf=wkhtmltopdf_bin)
pdf = pdfkit.from_string(html, False, options, **kwargs)
return pdf
def get_pdfkit_options(self):
"""
Returns ``self.pdfkit_options`` if set otherwise a default dict of options to supply to pdfkit.
:rtype: dict
"""
if self.pdfkit_options is not None:
return self.pdfkit_options
return {
'page-size': 'A4',
'encoding': 'UTF-8',
}
def get_filename(self):
"""
Return ``self.filename`` if set otherwise return the template basename with a ``.pdf`` extension.
:rtype: str
"""
if self.filename is None:
name = splitext(basename(self.template_name))[0]
return '{}.pdf'.format(name)
return self.filename
def render_html(self, *args, **kwargs):
"""
Renders the template.
:rtype: str
"""
static_url = '%s://%s%s' % (self.request.scheme, self.request.get_host(), settings.STATIC_URL)
media_url = '%s://%s%s' % (self.request.scheme, self.request.get_host(), settings.MEDIA_URL)
with override_settings(STATIC_URL=static_url, MEDIA_URL=media_url):
template = loader.get_template(self.template_name)
context = self.get_context_data(*args, **kwargs)
html = template.render(context)
return html
通过覆盖 get
,您已绕过 所有 该视图的内置功能,包括 get_template_names
的调用。这很少是正确的做法。
但是,鉴于您显示的代码,您不能从 render_html
中自己调用该方法的原因是什么?或者只是在那里内联逻辑。