Can model views in Flask-Admin hyperlink to other model views?

Question:

Let’s suppose we have a model, Foo, that references another model, User – and there are Flask-Admin’s ModelView for both.

On the Foo admin view page

enter image description here

I would like the entries in the User column to be linked to the corresponding User model view.

Do I need to modify one of Flask-Admin’s templates to achieve this?

(This is possible in the Django admin interface by simply outputting HTML for a given field and setting allow_tags (ref) True to bypass Django’s HTML tag filter)

Asked By: wodow

||

Answers:

Use column_formatters for this: https://flask-admin.readthedocs.org/en/latest/api/mod_model/#flask.ext.admin.model.BaseModelView.column_formatters

Idea is pretty simple: for a field that you want to display as hyperlink, either generate a HTML string and wrap it with Jinja2 Markup class (so it won’t be escaped in templates) or use macro helper: https://github.com/mrjoes/flask-admin/blob/master/flask_admin/model/template.py

Macro helper allows you to use custom Jinja2 macros in overridden template, which moves presentational logic to templates.

As far as URL is concerned, all you need is to find endpoint name generated (or provided) for the User model and do url_for('userview.edit_view', id=model.id) to generate the link.

Answered By: Joes

Some example code based on Joes’ answer:

class MyFooView(ModelView):

    def _user_formatter(view, context, model, name):
        return Markup(
            u"<a href='%s'>%s</a>" % (
                url_for('user.edit_view', id=model.user.id),
                model.user
            )
        ) if model.user else u""

    column_formatters = {
        'user': _user_formatter
    }
Answered By: wodow

extra information for @wodow, notice that model.user is wrong if you use pymongo as the backend, because the model in pymongo is a dict type, you can just use model['name'] to replace it

Answered By: Yuan Cheng

Adding this code to each of your models that have referenced by other models and flask-admin and jinja will take care of the name you want to display on the screen, just replace that with whatever you prefer:

def __unicode__(self):
    return self.name  # or self.id or whatever you prefer

for example:

class Role(db.Document, RoleMixin):
    name = db.StringField(max_length=80, unique=True)
    description = db.StringField(max_length=255)

    def __unicode__(self):
        return self.name

class MasterUser(db.Document, UserMixin):
    email = db.StringField(max_length=255)
    password = db.StringField(max_length=255)
    active = db.BooleanField(default=True)
    confirmed_at = db.DateTimeField()
    roles = db.ListField(db.ReferenceField(Role), default=[])
Answered By: H.Kalantari
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.