Skip to content

Commit 3e667fe

Browse files
Use formless default browsable API renderer (#973)
1 parent 8853521 commit 3e667fe

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from rest_framework.renderers import BrowsableAPIRenderer
2+
3+
4+
class BrowsableAPIRendererWithoutForms(BrowsableAPIRenderer):
5+
"""
6+
Renders the browsable api, but excludes the forms.
7+
8+
See https://github.com/WordPress/openverse/issues/970
9+
10+
CC BY 3.0 Brad Montgomery
11+
https://bradmontgomery.net/blog/disabling-forms-django-rest-frameworks-browsable-api/
12+
"""
13+
14+
def get_context(self, *args, **kwargs):
15+
ctx = super().get_context(*args, **kwargs)
16+
ctx["display_edit_forms"] = False
17+
return ctx
18+
19+
def show_form_for_method(self, view, method, request, obj):
20+
"""We never want to do this! So just return False."""
21+
return False
22+
23+
def get_rendered_html_form(self, data, view, method, request):
24+
"""Why render _any_ forms at all. This method should return
25+
rendered HTML, so let's simply return an empty string.
26+
"""
27+
return ""

api/catalog/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
146146
"DEFAULT_RENDERER_CLASSES": (
147147
"rest_framework.renderers.JSONRenderer",
148-
"rest_framework.renderers.BrowsableAPIRenderer",
148+
"catalog.api.utils.drf_renderer.BrowsableAPIRendererWithoutForms",
149149
"rest_framework_xml.renderers.XMLRenderer",
150150
),
151151
"DEFAULT_THROTTLE_CLASSES": (
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from rest_framework.request import Request
2+
from rest_framework.views import APIView
3+
4+
import pytest
5+
6+
from catalog.api.utils.drf_renderer import BrowsableAPIRendererWithoutForms
7+
8+
9+
@pytest.fixture
10+
def api_request(request_factory):
11+
return request_factory.get("/")
12+
13+
14+
@pytest.fixture
15+
def view():
16+
return APIView.as_view()
17+
18+
19+
@pytest.fixture
20+
def response(view, api_request):
21+
return view(api_request)
22+
23+
24+
def test_without_forms_renderer_context_should_not_show_edit_forms(
25+
api_request, response
26+
):
27+
"""
28+
See https://github.com/encode/django-rest-framework/blob/master/tests/test_renderers.py
29+
for example of test setup.
30+
"""
31+
cls = BrowsableAPIRendererWithoutForms()
32+
33+
parent_context = {
34+
"view": APIView(),
35+
"request": Request(api_request),
36+
"response": response,
37+
}
38+
39+
ctx = cls.get_context({}, "text/html", parent_context)
40+
41+
assert ctx["display_edit_forms"] is False
42+
43+
44+
parametrize_methods = pytest.mark.parametrize(
45+
"method", ("GET", "PUT", "POST", "DELETE", "OPTIONS")
46+
)
47+
48+
49+
@parametrize_methods
50+
def test_without_forms_renderer_show_form_for_method_returns_false(
51+
method, api_request, view
52+
):
53+
cls = BrowsableAPIRendererWithoutForms()
54+
55+
assert cls.show_form_for_method(view, method, api_request, None) is False
56+
57+
58+
@parametrize_methods
59+
def test_without_forms_renderer_get_rendered_html_form_empty(method, api_request, view):
60+
cls = BrowsableAPIRendererWithoutForms()
61+
62+
data = {}
63+
64+
assert cls.get_rendered_html_form(data, view, method, api_request) == ""

0 commit comments

Comments
 (0)