flask-admin not showing foreignkey columns
Asked Answered
K

4

12
class Parent(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(120))

    def __repr_(self):
        return '<Parent %r>' % (self.name)

admin.add_view(ModelView(Parent, db.session))


class Child(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(120))
    parent = db.Column(db.Integer, db.ForeignKey(Parent))

admin.add_view(ModelView(Child, db.session))

Hello -

The code above is an example of flask-admin page that I am trying to create. The goal is to have on Child's create page a text box for name and a drop down to select a parent.

With the above setup, there is only name field. The parent drop down box is missing.

Any ideas how to make it happen?

Ketch answered 23/4, 2013 at 3:39 Comment(0)
C
19

How about if you change the Child class to this:

class Child(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(120))
    parent_id = db.Column(db.Integer, db.ForeignKey('parent.id'))
    parent = db.relationship('Parent', backref=db.backref('children', lazy='dynamic'))

I don't know much about this, and I don't know if you need the back reference, but this setup works for me with Flask-Admin.

Contraoctave answered 24/4, 2013 at 13:29 Comment(3)
Awesome! I will try it tonight. Do I need any primaryjoin/secondaryjoin information? I've been getting a lot of errors about that. Hopefully your change will work awesomely!Ketch
Honestly, I wouldn't know. I've never seen anything about primaryjoin/secondaryjoin with Flask-Alchemy or Flask-Admin.Contraoctave
Reason why it works: Flask-Admin works with ORM objects, such as models, relations, etc. By default, Flask-Admin will ignore foreign keys in models as they just contain some number and Flask-Admin wants concrete ORM object to work with. So, when you have foreign key on the model, make sure you don't forget ORM level link between models - a relation. Flask-Admin will use this link to display related model(s). And no, you don't need to do fancy stuff or add backrefs to make it work.Descant
M
20

You likely need to specify some additional options to flask-admin via a subclass:

class ChildView(ModelView):
    column_display_pk = True # optional, but I like to see the IDs in the list
    column_hide_backrefs = False
    column_list = ('id', 'name', 'parent')


admin.add_view(ChildView(Parent, db.session))
Mcalister answered 25/4, 2013 at 9:19 Comment(1)
Was looking for a way to display the PKs, perfect!Lindbom
C
19

How about if you change the Child class to this:

class Child(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(120))
    parent_id = db.Column(db.Integer, db.ForeignKey('parent.id'))
    parent = db.relationship('Parent', backref=db.backref('children', lazy='dynamic'))

I don't know much about this, and I don't know if you need the back reference, but this setup works for me with Flask-Admin.

Contraoctave answered 24/4, 2013 at 13:29 Comment(3)
Awesome! I will try it tonight. Do I need any primaryjoin/secondaryjoin information? I've been getting a lot of errors about that. Hopefully your change will work awesomely!Ketch
Honestly, I wouldn't know. I've never seen anything about primaryjoin/secondaryjoin with Flask-Alchemy or Flask-Admin.Contraoctave
Reason why it works: Flask-Admin works with ORM objects, such as models, relations, etc. By default, Flask-Admin will ignore foreign keys in models as they just contain some number and Flask-Admin wants concrete ORM object to work with. So, when you have foreign key on the model, make sure you don't forget ORM level link between models - a relation. Flask-Admin will use this link to display related model(s). And no, you don't need to do fancy stuff or add backrefs to make it work.Descant
A
4

Here is an all-inclusive solution that requires no manual maintenance.

from sqlalchemy import inspect

class ChildView(ModelView):
    column_display_pk = True # optional, but I like to see the IDs in the list
    column_hide_backrefs = False
    column_list = [c_attr.key for c_attr in inspect(Child).mapper.column_attrs]


admin.add_view(ChildView(Child, db.session))
Aerobic answered 23/8, 2019 at 17:44 Comment(0)
P
2

For what it is worth, none of the solutions listed here worked for me. I was facing the issue where foreign keys were not showing up in Flask-Admin.

This is what worked for them to show up:

class CustomModelViewName(ModelView):
    can_delete = True
    column_hide_backrefs = False
    column_list = ["column_name", "column_name", "etc", "etc", "etc"]
    column_searchable_list = ["column_name"]
Pamela answered 25/9, 2019 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.