Search code examples
pythonsqlalchemyflaskflask-sqlalchemyflask-admin

Display first element of a one-to-many relationship in Flask-Admin


I'm currently using Flask-Admin to create an admin screen but I'm running into a roadblock. Suppose I have two classes that look like this:

class Part(db.Model):
  id = db.Column(db.Integer, primary_key=True, unique=True)
  part_data = db.relationship("PartHistory", backref="part")
  name = db.Column(db.String(255))

class PartHistory(db.Model):
  id = db.Column(db.Integer, primary_key=True, unique=True)
  part_id = db.Column(db.Integer, db.ForeignKey('part.id'))
  date_checked = db.Column(db.Date)

Part has a one-to-many relationship on PartHistory. I'd like to create a view that shows the Part name in one column and the first date_checked in the other column. I tried something like this:

column_list = ("name", "part_data[0].date_checked")

But that doesn't seem to work. It also seems like I'm going about this the wrong way. Any tips would be appreciated.


Solution

  • One way would be to use column-property to define a computed column which would be populated with the field you need. Below I used a min value, but you can construct arbitrary query to get the first by ID (best way to achieve that would be backend-specific):

    class Part(db.Model):
      # ...
      date_checked = db.column_property(
            db.select([db.func.min(PartHistory.date_checked)]).\
                where(PartHistory.part_id==id).\
                correlate_except(PartHistory)
        )
    

    Note that you might not be able to sort by this column though.