lapinkoira
lapinkoira

Reputation: 8988

xframe_options_exempt for a Django TemplateView

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

Answers (3)

Alasdair
Alasdair

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

zepp133
zepp133

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

lapinkoira
lapinkoira

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

Related Questions