From 90126627eba18f9fc7878010327b8207ce38960e Mon Sep 17 00:00:00 2001 From: Craig de Stigter Date: Thu, 10 May 2018 12:11:38 +1200 Subject: [PATCH] Fix AttributeError in base.html when called without `response_headers` This happens when using a `404.html` which extends DRF's `base.html` and is called by a `Resolver404`. Since `Resolver404` goes via django's `handler404` and not via DRF's exception handling, it doesn't get the extra context. Since the `|items` filter doesn't check for `response_headers` being null (missing) it attempts to call `.items()`, thus raising an AttributeError. Originally I solved this in the template by guarding the `for` loop with a `if response_headers`. However @rpkilby expressed a preference for doing the check inside the `items` filter instead. --- rest_framework/templatetags/rest_framework.py | 4 ++++ tests/test_templates.py | 7 +++++++ 2 files changed, 11 insertions(+) create mode 100644 tests/test_templates.py diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py index 2a2459b37..36aa9e8b3 100644 --- a/rest_framework/templatetags/rest_framework.py +++ b/rest_framework/templatetags/rest_framework.py @@ -240,6 +240,10 @@ def items(value): lookup. See issue #4931 Also see: https://stackoverflow.com/questions/15416662/django-template-loop-over-dictionary-items-with-items-as-key """ + if value is None: + # `{% for k, v in value.items %}` doesn't raise when value is None or + # not in the context, so neither should `{% for k, v in value|items %}` + return [] return value.items() diff --git a/tests/test_templates.py b/tests/test_templates.py new file mode 100644 index 000000000..a296395f6 --- /dev/null +++ b/tests/test_templates.py @@ -0,0 +1,7 @@ +from django.shortcuts import render + + +def test_base_template_with_no_context(): + # base.html should be renderable with no context, + # so it can be easily extended. + render({}, 'rest_framework/base.html')