Flask Admin: extra_js and url_for
Asked Answered
P

1

6

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?

Prolamine answered 25/5, 2018 at 14:44 Comment(0)
T
11

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 !

Teece answered 21/6, 2018 at 9:36 Comment(2)
Thanks, it helped! Just to point out for other noobs. AdminModelView is just the regular ModelView class, that confused me first.Bechtel
It's also possible to add it to a single route, for instance if you want to add just to the create route your would do: class MyModelView(AdminModelView): @expose("/new/", methods=("GET", "POST")) def create_view(self): self.extra_js = [url_for("static", filename="js/whatever.js")] return super().create_view()Fungicide

© 2022 - 2024 — McMap. All rights reserved.