diff --git a/rest_framework/templates/rest_framework/admin/detail.html b/rest_framework/templates/rest_framework/admin/detail.html
index 759fa163d..42cd1a36d 100644
--- a/rest_framework/templates/rest_framework/admin/detail.html
+++ b/rest_framework/templates/rest_framework/admin/detail.html
@@ -1,7 +1,7 @@
{% load rest_framework %}
- {% for key, value in results.items %}
+ {% for key, value in results|items %}
{% if key in details %}
{{ key|capfirst }} | {{ value|format_value }} |
{% endif %}
diff --git a/rest_framework/templates/rest_framework/admin/dict_value.html b/rest_framework/templates/rest_framework/admin/dict_value.html
index 3392c901b..ef47b7228 100644
--- a/rest_framework/templates/rest_framework/admin/dict_value.html
+++ b/rest_framework/templates/rest_framework/admin/dict_value.html
@@ -1,10 +1,10 @@
{% load rest_framework %}
- {% for key, value in value.items %}
+ {% for k, v in value|items %}
- {{ key|format_value }} |
- {{ value|format_value }} |
+ {{ k|format_value }} |
+ {{ v|format_value }} |
{% endfor %}
diff --git a/rest_framework/templates/rest_framework/admin/list.html b/rest_framework/templates/rest_framework/admin/list.html
index 6044ebb38..fd394d44e 100644
--- a/rest_framework/templates/rest_framework/admin/list.html
+++ b/rest_framework/templates/rest_framework/admin/list.html
@@ -6,7 +6,7 @@
{% for row in results %}
- {% for key, value in row.items %}
+ {% for key, value in row|items %}
{% if key in columns %}
{{ value|format_value }}
diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py
index cfba054f6..d62ac4800 100644
--- a/rest_framework/templatetags/rest_framework.py
+++ b/rest_framework/templatetags/rest_framework.py
@@ -163,6 +163,17 @@ def format_value(value):
return six.text_type(value)
+@register.filter
+def items(value):
+ """
+ Simple filter to return the items of the dict. Useful when the dict may
+ have a key 'items' which is resolved first in Django tempalte dot-notation
+ lookup. See issue #4931
+ Also see: https://stackoverflow.com/questions/15416662/django-template-loop-over-dictionary-items-with-items-as-key
+ """
+ return value.items()
+
+
@register.filter
def add_nested_class(value):
if isinstance(value, dict):
diff --git a/tests/test_renderers.py b/tests/test_renderers.py
index eba5b8104..12ac2dfc8 100644
--- a/tests/test_renderers.py
+++ b/tests/test_renderers.py
@@ -648,3 +648,47 @@ class AdminRendererTests(TestCase):
assert result == ''
assert response.status_code == status.HTTP_303_SEE_OTHER
assert response['Location'] == 'http://example.com'
+
+ def test_render_dict(self):
+ factory = APIRequestFactory()
+
+ class DummyView(APIView):
+ renderer_classes = (AdminRenderer, )
+
+ def get(self, request):
+ return Response({'foo': 'a string'})
+ view = DummyView.as_view()
+ request = factory.get('/')
+ response = view(request)
+ response.render()
+ self.assertInHTML(' |
Foo | a string |
', str(response.content))
+
+ def test_render_dict_with_items_key(self):
+ factory = APIRequestFactory()
+
+ class DummyView(APIView):
+ renderer_classes = (AdminRenderer, )
+
+ def get(self, request):
+ return Response({'items': 'a string'})
+
+ view = DummyView.as_view()
+ request = factory.get('/')
+ response = view(request)
+ response.render()
+ self.assertInHTML('Items | a string |
', str(response.content))
+
+ def test_render_dict_with_iteritems_key(self):
+ factory = APIRequestFactory()
+
+ class DummyView(APIView):
+ renderer_classes = (AdminRenderer, )
+
+ def get(self, request):
+ return Response({'iteritems': 'a string'})
+
+ view = DummyView.as_view()
+ request = factory.get('/')
+ response = view(request)
+ response.render()
+ self.assertInHTML('Iteritems | a string |
', str(response.content))