API 被 django.template.exceptions.TemplateDoesNotExist 暗杀
Wagtail API v2 django.template.exceptions.TemplateDoesNotExist
我已经按照 docs 中的规定配置了 Wagtail API
,并且在使用 curl
时效果很好:
$ curl -LsD- http://127.0.0.1:8080/rest/p/
HTTP/1.1 200 OK
Date: Fri, 22 May 2020 17:33:58 GMT
Server: WSGIServer/0.2 CPython/3.8.2
Content-Type: application/json
Vary: Accept, Cookie
Allow: GET, HEAD, OPTIONS
X-Frame-Options: DENY
Content-Length: 433
X-Content-Type-Options: nosniff
{
"meta": {
"total_count": 1
},
"items": [
{
"id": 2,
"meta": {
"type": "wagtailcore.Page",
"detail_url": "http://localhost/rest/p/2/",
"html_url": "http://localhost/",
"slug": "home",
"first_published_at": null
},
"title": "Welcome to your new Wagtail site!"
}
]
}
Wagtail 文档声明如下:
Optionally, you may also want to add rest_framework to INSTALLED_APPS. This would make the API browsable when viewed from a web browser but is not required for basic JSON-formatted output.
这是真的,因为 API 通过 curl
工作正常,但是如果我不将 rest_framework
添加到 INSTALLED_APPS
然后尝试访问同样 url 通过浏览器我得到 http 500
,即因为应用程序抛出异常:
Internal Server Error: /rest/p/
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/usr/local/lib/python3.8/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.8/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/usr/local/lib/python3.8/site-packages/rest_framework/renderers.py", line 723, in render
template = loader.get_template(self.template)
File "/usr/local/lib/python3.8/site-packages/django/template/loader.py", line 19, in get_template
raise TemplateDoesNotExist(template_name, chain=chain)
django.template.exceptions.TemplateDoesNotExist: rest_framework/api.html
所以在我看来,如果我不想用 django
例外阻塞我的电子邮件,那么 rest_framework
是我的产品站点设置中的强制应用程序吗?我错过了一些配置细节吗?解决此问题的最佳方法是什么?
我不希望我的实时网站一直抛出 500,而且我并不严格需要这个漂亮而闪亮的 api 界面。
编辑:
添加了相关的 rest_framework
配置:
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticatedOrReadOnly",
],
"DEFAULT_RENDERER_CLASSES": [
"rest_framework.renderers.JSONRenderer",
],
}
编辑:
通过查看调试回溯,似乎 Wagtail
以某种方式强制执行 rest_framework.renderers.BrowsableAPIRenderer
渲染器,即使 REST_FRAMEWORK
未配置为使用它?
编辑:
显然 Wagtail
确实忽略了 REST_FRAMEWORK
设置,而是使用硬编码 renderer_classes,即 [JSONRenderer, BrowsableAPIRenderer]
.
这是因为 rest_framework
将 TemplateHTMLRenderer
作为默认渲染器之一。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.TemplateHTMLRenderer',
],
...
}
为了呈现模板,它必须使用 Django 模板实用程序找到它们。为了让该工具在 rest_framework
包中搜索模板,必须将其添加到 INSTALED_APPS
。
因此,要解决此问题,请覆盖 REST_FRAMEWORK
设置并删除 TemplateHTMLRenderer
,因为您只需要 JSONRenderer
。
您可以阅读有关 DRF settings.
的更多信息
可能是 bug in a Wagtail
as it ignores REST_FRAMEWORK
configuration in the settings and instead uses hardcoded renderer_classes,目前是 [JSONRenderer, BrowsableAPIRenderer]
。
要克服这一问题,可以像下面这样设置 Wagtail API
:
from django.conf import settings
from wagtail.api.v2.views import PagesAPIViewSet
from wagtail.api.v2.router import WagtailAPIRouter
if not settings.DEBUG:
from rest_framework.renderers import JSONRenderer
class ProdPagesAPIViewSet(PagesAPIViewSet):
renderer_classes = [JSONRenderer]
PagesAPIViewSet = ProdPagesAPIViewSet
api_router = WagtailAPIRouter("wagtailapi")
api_router.register_endpoint("p", PagesAPIViewSet)
我已经按照 docs 中的规定配置了 Wagtail API
,并且在使用 curl
时效果很好:
$ curl -LsD- http://127.0.0.1:8080/rest/p/
HTTP/1.1 200 OK
Date: Fri, 22 May 2020 17:33:58 GMT
Server: WSGIServer/0.2 CPython/3.8.2
Content-Type: application/json
Vary: Accept, Cookie
Allow: GET, HEAD, OPTIONS
X-Frame-Options: DENY
Content-Length: 433
X-Content-Type-Options: nosniff
{
"meta": {
"total_count": 1
},
"items": [
{
"id": 2,
"meta": {
"type": "wagtailcore.Page",
"detail_url": "http://localhost/rest/p/2/",
"html_url": "http://localhost/",
"slug": "home",
"first_published_at": null
},
"title": "Welcome to your new Wagtail site!"
}
]
}
Wagtail 文档声明如下:
Optionally, you may also want to add rest_framework to INSTALLED_APPS. This would make the API browsable when viewed from a web browser but is not required for basic JSON-formatted output.
这是真的,因为 API 通过 curl
工作正常,但是如果我不将 rest_framework
添加到 INSTALLED_APPS
然后尝试访问同样 url 通过浏览器我得到 http 500
,即因为应用程序抛出异常:
Internal Server Error: /rest/p/
Traceback (most recent call last):
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
response = get_response(request)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 143, in _get_response
response = response.render()
File "/usr/local/lib/python3.8/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/usr/local/lib/python3.8/site-packages/rest_framework/response.py", line 70, in rendered_content
ret = renderer.render(self.data, accepted_media_type, context)
File "/usr/local/lib/python3.8/site-packages/rest_framework/renderers.py", line 723, in render
template = loader.get_template(self.template)
File "/usr/local/lib/python3.8/site-packages/django/template/loader.py", line 19, in get_template
raise TemplateDoesNotExist(template_name, chain=chain)
django.template.exceptions.TemplateDoesNotExist: rest_framework/api.html
所以在我看来,如果我不想用 django
例外阻塞我的电子邮件,那么 rest_framework
是我的产品站点设置中的强制应用程序吗?我错过了一些配置细节吗?解决此问题的最佳方法是什么?
我不希望我的实时网站一直抛出 500,而且我并不严格需要这个漂亮而闪亮的 api 界面。
编辑:
添加了相关的 rest_framework
配置:
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticatedOrReadOnly",
],
"DEFAULT_RENDERER_CLASSES": [
"rest_framework.renderers.JSONRenderer",
],
}
编辑:
通过查看调试回溯,似乎 Wagtail
以某种方式强制执行 rest_framework.renderers.BrowsableAPIRenderer
渲染器,即使 REST_FRAMEWORK
未配置为使用它?
编辑:
显然 Wagtail
确实忽略了 REST_FRAMEWORK
设置,而是使用硬编码 renderer_classes,即 [JSONRenderer, BrowsableAPIRenderer]
.
这是因为 rest_framework
将 TemplateHTMLRenderer
作为默认渲染器之一。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.TemplateHTMLRenderer',
],
...
}
为了呈现模板,它必须使用 Django 模板实用程序找到它们。为了让该工具在 rest_framework
包中搜索模板,必须将其添加到 INSTALED_APPS
。
因此,要解决此问题,请覆盖 REST_FRAMEWORK
设置并删除 TemplateHTMLRenderer
,因为您只需要 JSONRenderer
。
您可以阅读有关 DRF settings.
可能是 bug in a Wagtail
as it ignores REST_FRAMEWORK
configuration in the settings and instead uses hardcoded renderer_classes,目前是 [JSONRenderer, BrowsableAPIRenderer]
。
要克服这一问题,可以像下面这样设置 Wagtail API
:
from django.conf import settings
from wagtail.api.v2.views import PagesAPIViewSet
from wagtail.api.v2.router import WagtailAPIRouter
if not settings.DEBUG:
from rest_framework.renderers import JSONRenderer
class ProdPagesAPIViewSet(PagesAPIViewSet):
renderer_classes = [JSONRenderer]
PagesAPIViewSet = ProdPagesAPIViewSet
api_router = WagtailAPIRouter("wagtailapi")
api_router.register_endpoint("p", PagesAPIViewSet)