Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask Admin: extra_js and url_for

I'm trying to load a script on a certain ModelView in my admin pages:

class CustomView(ModelView):
    # Neither approach works here:
    # with current_app.app_context(), current_app.test_request_context():
    extra_js = [url_for('static', filename='admin/admin.js')]

With the app_context() commented out, I get this error:

RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available.

Uncommenting the app_context gives me this error:

RuntimeError: Working outside of application context. This typically means that you attempted to use functionality that needed to interface with the current application object in some way. To solve this, set up an application context with app.app_context(). See the documentation for more information.

I also tried adding context when I set up the Admin views, but get the same error:

# ADMIN
with app.app_context():
    admin = Admin(app, name='Custom', template_mode='bootstrap3', index_view=MyIndex(), base_template='admin/base.html')
    admin.add_view(CustomView(User, db.session))

So, how can I pass the app context appropriately to load my script for this view?

like image 945
AlxVallejo Avatar asked Jan 29 '23 01:01

AlxVallejo


1 Answers

I found a solution, I am not sure it answers perfectly your need, but as long as I felt on this topic by googling my problem I hope this can help fellows.

So, in order to make url_for available in flask admin extra_js property, I just defined my extra_js property in my class that implements the ModelView base class of flask admin by overriding the render method.. The snippet equals thousands words:

class MyModelView(AdminModelView):

    def render(self, template, **kwargs):
        """
        using extra js in render method allow use
        url_for that itself requires an app context
        """
        self.extra_js = [url_for("static", filename="js/whatever.js")]

        return super(MyModelView, self).render(template, **kwargs)

Hope this helps !

like image 160
utopman Avatar answered Feb 24 '23 14:02

utopman