Skip to content

Commit dc4a98f

Browse files
author
Carlton Gibson
authored
Fix documentation data rendering (#5472)
* Add failing test for #5395 * Add data filter for use in templates Closes #5395 * Fix isort
1 parent 063534a commit dc4a98f

File tree

6 files changed

+61
-7
lines changed

6 files changed

+61
-7
lines changed

rest_framework/templates/rest_framework/docs/document.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ <h1>{{ document.title }}</h1>
1313
{% if 'javascript' in langs %}{% include "rest_framework/docs/langs/javascript-intro.html" %}{% endif %}
1414
</div>
1515
</div>
16-
{% if document.data %}
17-
{% for section_key, section in document.data|items %}
16+
{% if document|data %}
17+
{% for section_key, section in document|data|items %}
1818
{% if section_key %}
1919
<h2 id="{{ section_key }}" class="coredocs-section-title">{{ section_key }} <a href="#{{ section_key }}"><i class="fa fa-link" aria-hidden="true"></i>
2020
</a></h2>

rest_framework/templates/rest_framework/docs/sidebar.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ <h3 class="brand"><a href="#">{{ document.title }}</a></h3>
55
<i class="fa fa-bars fa-2x toggle-btn" data-toggle="collapse" data-target="#menu-content"></i>
66
<div class="menu-list">
77
<ul id="menu-content" class="menu-content collapse out">
8-
{% if document.data %}
9-
{% for section_key, section in document.data|items %}
8+
{% if document|data %}
9+
{% for section_key, section in document|data|items %}
1010
<li data-toggle="collapse" data-target="#{{ section_key }}-dropdown" class="collapsed">
1111
<a><i class="fa fa-dot-circle-o fa-lg"></i> {% if section_key %}{{ section_key }}{% else %}API Endpoints{% endif %} <span class="arrow"></span></a>
1212
<ul class="sub-menu {% if section_key %}collapse{% endif %}" id="{{ section_key }}-dropdown">

rest_framework/templatetags/rest_framework.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,20 @@ def items(value):
245245
return value.items()
246246

247247

248+
@register.filter
249+
def data(value):
250+
"""
251+
Simple filter to access `data` attribute of object,
252+
specifically coreapi.Document.
253+
254+
As per `items` filter above, allows accessing `document.data` when
255+
Document contains Link keyed-at "data".
256+
257+
See issue #5395
258+
"""
259+
return value.data
260+
261+
248262
@register.filter
249263
def schema_links(section, sec_key=None):
250264
"""

tests/conftest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def pytest_configure():
2626
{
2727
'BACKEND': 'django.template.backends.django.DjangoTemplates',
2828
'APP_DIRS': True,
29+
'OPTIONS': {
30+
"debug": True, # We want template errors to raise
31+
}
2932
},
3033
],
3134
MIDDLEWARE=MIDDLEWARE,

tests/test_renderers.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
from django.utils.safestring import SafeText
1515
from django.utils.translation import ugettext_lazy as _
1616

17+
import coreapi
1718
from rest_framework import permissions, serializers, status
1819
from rest_framework.renderers import (
19-
AdminRenderer, BaseRenderer, BrowsableAPIRenderer,
20+
AdminRenderer, BaseRenderer, BrowsableAPIRenderer, DocumentationRenderer,
2021
HTMLFormRenderer, JSONRenderer, StaticHTMLRenderer
2122
)
2223
from rest_framework.request import Request
@@ -706,3 +707,32 @@ def get(self, request):
706707
response = view(request)
707708
response.render()
708709
self.assertInHTML('<tr><th>Iteritems</th><td>a string</td></tr>', str(response.content))
710+
711+
712+
class TestDocumentationRenderer(TestCase):
713+
714+
def test_document_with_link_named_data(self):
715+
"""
716+
Ref #5395: Doc's `document.data` would fail with a Link named "data".
717+
As per #4972, use templatetag instead.
718+
"""
719+
document = coreapi.Document(
720+
title='Data Endpoint API',
721+
url='https://api.example.org/',
722+
content={
723+
'data': coreapi.Link(
724+
url='/data/',
725+
action='get',
726+
fields=[],
727+
description='Return data.'
728+
)
729+
}
730+
)
731+
732+
factory = APIRequestFactory()
733+
request = factory.get('/')
734+
735+
renderer = DocumentationRenderer()
736+
737+
html = renderer.render(document, accepted_media_type="text/html", renderer_context={"request": request})
738+
assert '<h1>Data Endpoint API</h1>' in html

tests/urls.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
"""
2-
Blank URLConf just to keep the test suite happy
2+
URLConf for test suite.
3+
4+
We need only the docs urls for DocumentationRenderer tests.
35
"""
4-
urlpatterns = []
6+
from django.conf.urls import url
7+
from rest_framework.documentation import include_docs_urls
8+
9+
urlpatterns = [
10+
url(r'^docs/', include_docs_urls(title='Test Suite API')),
11+
]

0 commit comments

Comments
 (0)