Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix AttributeError in base.html when called without response_headers #5981

Merged

Conversation

craigds
Copy link
Contributor

@craigds craigds commented May 10, 2018

Description

We use a 404.html which extends rest_framework/base.html. With the default handler404 implementation, this template is rendered when you encounter a Resolver404. With DRF <3.6 this worked fine. Since then it throws an AttributeError. I traced the problem to 0173e9b.

Since Resolver404 goes via django's handler404 and not via DRF's exception handling,
it doesn't get any extra context.

Since the |items filter doesn't check for response_headers being null (missing) it attempts
to call <None>.items(), thus raising an AttributeError.

This fixes the problem by checking for the presence of response_headers before calling |items with it.

Possible alternative solutions

  • This could alternatively be solved in the items filter, making it just check for null before continuing. That might mask other problems elsewhere though.
  • If there was an easy way to delegate handler404 etc to a DRF-based implementation which added the correct context, that might be more ideal. I couldn't find an easy way to do this.

craigds added a commit to koordinates/django-rest-framework that referenced this pull request May 10, 2018
Backport of my fix for encode#5981

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 `<None>.items()`, thus raising an AttributeError.

Alternatives:
 * This could alternatively be solved in the `items` filter, making it just check for null before continuing.
 * If there was an easy way to delegate `handler404` etc to a DRF-based implementation which added the
   correct context, that might be an ideal solution. I couldn't find an easy way to do this.
craigds added a commit to koordinates/django-rest-framework that referenced this pull request May 10, 2018
Backport of my fix for encode#5981

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 `<None>.items()`, thus raising an AttributeError.

Alternatives:
 * This could alternatively be solved in the `items` filter, making it just check for null before continuing.
 * If there was an easy way to delegate `handler404` etc to a DRF-based implementation which added the
   correct context, that might be an ideal solution. I couldn't find an easy way to do this.
@rpkilby
Copy link
Member

rpkilby commented May 10, 2018

This could alternatively be solved in the items filter, making it just check for null before continuing. That might mask other problems elsewhere though.

This seems like a preferable solution to me. dict.items doesn't raise an exception, and neither should dict|items. It seems unnecessary to require wrapping the items filter in an if condition.

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 `<None>.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.
@craigds craigds force-pushed the fix-attributeerror-in-base-template branch from 38ab10d to 9012662 Compare May 11, 2018 02:38
@craigds
Copy link
Contributor Author

craigds commented May 11, 2018

👍 done

Copy link
Collaborator

@carltongibson carltongibson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. Nice. Thanks.

@carltongibson carltongibson added this to the 3.9 Release milestone May 11, 2018
@carltongibson carltongibson merged commit 9629886 into encode:master May 11, 2018
@craigds craigds deleted the fix-attributeerror-in-base-template branch May 14, 2018 23:13
craigds added a commit to koordinates/django-rest-framework that referenced this pull request Jun 14, 2018
Backport of my fix for encode#5981

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 `<None>.items()`, thus raising an AttributeError.

Alternatives:
 * This could alternatively be solved in the `items` filter, making it just check for null before continuing.
 * If there was an easy way to delegate `handler404` etc to a DRF-based implementation which added the
   correct context, that might be an ideal solution. I couldn't find an easy way to do this.
craigds added a commit to koordinates/django-rest-framework that referenced this pull request Jun 14, 2018
Backport of my fix for encode#5981

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 `<None>.items()`, thus raising an AttributeError.

Alternatives:
 * This could alternatively be solved in the `items` filter, making it just check for null before continuing.
 * If there was an easy way to delegate `handler404` etc to a DRF-based implementation which added the
   correct context, that might be an ideal solution. I couldn't find an easy way to do this.
craigds added a commit to koordinates/django-rest-framework that referenced this pull request May 28, 2019
craigds added a commit to koordinates/django-rest-framework that referenced this pull request May 28, 2019
pchiquet pushed a commit to pchiquet/django-rest-framework that referenced this pull request Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants