Reputation: 8988
I am trying to add the decorator @xframe_options_exempt into a django template view but it complais with a
Exception Value: 'dict' object has no attribute 'xframe_options_exempt'
I noticed in Django 1.9 docs the decorator is used for views with a request parameter and I am using a TemplateView.
Is it possible to use it like this?
class MyView(TemplateView):
"""
"""
template_name = 'app/template.html'
from django.views.decorators.clickjacking import xframe_options_exempt
@xframe_options_exempt
def get_context_data(self, **kwargs):
context = {}
context['test'] = 'hello'
return context
Basically I need to embed a django template view into an iframe
Upvotes: 9
Views: 7501
Reputation: 308849
When you are decorating class based views, you should use method_decorator
. You should override a method that takes the request
as an argument, e.g. dispatch
(will apply to all request types) or get
(will apply to get requests but not post requests). As you found, decorating get_context_data
will not work.
class MyView(TemplateView):
@method_decorator(xframe_options_exempt):
def dispatch(self, *args, **kwargs):
return super(MyView, self).dispatch(*args, **kwargs)
Note that by using super()
you don't have to duplicate the code from TemplateView
.
You can decorate the class if you prefer (Django 1.9+)
@method_decorator(xframe_options_exempt, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
Upvotes: 24
Reputation: 1610
Based on the available @xframe_options_exempt
decorator, you can also implement a mixin class to be mixed into your view classes:
class XFrameOptionsExemptMixin:
@xframe_options_exempt
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
class SomeView(XFrameOptionsExemptMixin, TemplateView):
…
Upvotes: 5
Reputation: 8988
Well, if anyone else has this problem, this decorator cannot be applied to get_context_data method, but you can override the get method from the TemplateView, something like this:
class MyView(TemplateView):
"""
"""
template_name = 'app/template.html'
from django.views.decorators.clickjacking import xframe_options_exempt
@xframe_options_exempt
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = {}
context['test'] = 'hello'
return context
And this will do the trick
Upvotes: 1