简体   繁体   中英

Altering the response headers of Flask-Admin views?

I am trying to alter the response headers for all the Flask-Admin views on my site. Specifically I want to set caching headers.

For normal blueprints it is pretty straightforward:

@my_blueprint.after_request
def add_my_headers(response):
    h = {
        'Cache-Control': 'no-cache, no-store, must-revalidate',
        'Pragma': 'no-cache',
        'Expires': '0'
     }
    response.headers.extend(h)
    return response

And this will work.

But for Flask-Admin views I have been doing something like:

@app.after_request
def add_my_headers(response):
    if request.endpoint[:5] == 'admin':
        h = {
            'Cache-Control': 'no-cache, no-store, must-revalidate',
            'Pragma': 'no-cache',
            'Expires': '0'
             }
        response.headers.extend(h)
        return response
    return response

This works just fine but it seems quite a messy way to do it.

For some reason Flask-Admin doesn't seem to offer a way to register an after_request function before the blueprint gets registered to the main app.

I was able to get it to work by overriding the create_blueprint method of the Flask-Admin BaseView class. Here is my index view.

class MyIndexView(AdminIndexView):
    def create_blueprint(self, admin):
        """
            Create Flask blueprint.
        """
        self.blueprint = super(AdminIndexView, self).create_blueprint(admin)

        def my_cache_headers(response):
            h = {
                'Cache-Control': 'no-cache, no-store, must-revalidate',
                'Pragma': 'no-cache',
                'Expires': '0'
                 }
            response.headers.extend(h)
            return response

        self.blueprint.after_request(my_cache_headers)

        return self.blueprint

    @expose('/')
    def index(self):
        return self.render('admin/index.html')

This ends up working. I suppose the issue is that I want these headers to apply to all of my /admin/ views so maybe the best way is to use an @app.after_request decorator and just check for the /admin endpoint.

However it would be nice to be able to register before or after request functions without having to mess around too much (like overriding the create_blueprint method for specific admin views) Or is that fine?

Another method I have used is adding to the app.after_request_funcs dict.

app.after_request_funcs.setdefault('admin', []).append(my_cache_headers)

After trying these different methods I am beginning to think my original way of doing it might be the best way?

My question essentially is, How do I set custom response headers on my Flask-Admin views?

Flask-Admin GitHub

You could change method render() in BaseView to add whatever headers you want:

from flask_admin.base import BaseView
from flask_admin import babel
from flask import current_app, render_template, make_response
from flask_admin import helpers as h

def render(self, template, **kwargs):
    kwargs['admin_view'] = self
    kwargs['admin_base_template'] = self.admin.base_template

    kwargs['_gettext'] = babel.gettext
    kwargs['_ngettext'] = babel.ngettext
    kwargs['h'] = h

    kwargs['get_url'] = self.get_url
    kwargs['config'] = current_app.config
    kwargs.update(self._template_args)

    response = make_response(render_template(template, **kwargs), 200)
    response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
    response.headers['Pragma'] = 'no-cache'
    response.headers['Expires'] = '0'
    return response

BaseView.render = render

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM