flask-admin: How to display meaningful foreign key info in edit and create forms?
Asked Answered
J

2

5

I have a Flask-Admin interface to a flask app using SQLAlechemy, and I can't seem to figure out how to handle foreign keys. Specifically, I have the following two models:

class DoctorType(db.Model):
    __tablename__ = 'doctor_type'
    id = db.Column(db.Integer, primary_key=True)
    doctor_type_english_name = db.Column(db.Unicode(255))
    doctors = db.relationship('Doctor')

    def __unicode__(self):
        return self.doctor_type_english_name

class Doctor(db.Model):
    __tablename__ = 'doctor'
    id = db.Column(db.Integer, primary_key=True)
    doctor_english_name = db.Column(db.Unicode(255))
    doctor_type_id = db.Column(db.Integer, db.ForeignKey('doctor_type.id'))

    def __unicode__(self):
        return self.doctor_english_name

I'd like for the doctor_type_id field in the create or edit forms of flask-admin to be a dropdown list of doctor_type_english_name rather than just being an integer input like this:

Doctor Type Input Field

I have __unicode__ functions on the models (I'm using python 2.7). I tried tinkering with form_ajax_refs in my custom form views but with no success. Any help would be much appreciated!

Jessiejessika answered 29/5, 2017 at 22:44 Comment(0)
J
5

It turns out what I was missing was a relationship from the Doctor class to the DoctorType class. I implemented this with a backref in the DoctorType.doctors relationship:

class DoctorType(db.Model):
    __tablename__ = 'doctor_type'
    id = db.Column(db.Integer, primary_key=True)
    doctor_type_english_name = db.Column(db.Unicode(255))
    doctors = db.relationship('Doctor', backref='doctor_type')

    def __unicode__(self):
        return self.doctor_type_english_name

Once I added that, the "Doctor" edit and create forms in flask-admin had a new field called Doctor Type that was a dropdown of the DoctorType.doctor_type_english_name values, and the Doctor Type ID field was gone by default. This is the behavior I was wanting.

Jessiejessika answered 31/5, 2017 at 23:56 Comment(0)
R
13

Implement __repr__ in define of data model.

class DoctorType(db.Model):
    #...
    def __repr__(self):
        return self. doctor_type_english_name
Ribal answered 29/5, 2017 at 23:48 Comment(4)
Adding __repr__ would not help since that does the same thing as the __unicode__ function in this case. The foreign key still shows up as an integer field in the edit and delete forms. Thanks for the speedy response though!Jessiejessika
Have you try implement __repr__ in your model define? __repr__ and __unicode__ both works for me.Ribal
I did. I realized it was the relationship that was missing, not the __repr__. Thanks again for the answer though! I upvoted your answer but I don't have enough rep to upvote anything yet :-(Jessiejessika
This is wonderful. It works like a charm, with so little code!Emeryemesis
J
5

It turns out what I was missing was a relationship from the Doctor class to the DoctorType class. I implemented this with a backref in the DoctorType.doctors relationship:

class DoctorType(db.Model):
    __tablename__ = 'doctor_type'
    id = db.Column(db.Integer, primary_key=True)
    doctor_type_english_name = db.Column(db.Unicode(255))
    doctors = db.relationship('Doctor', backref='doctor_type')

    def __unicode__(self):
        return self.doctor_type_english_name

Once I added that, the "Doctor" edit and create forms in flask-admin had a new field called Doctor Type that was a dropdown of the DoctorType.doctor_type_english_name values, and the Doctor Type ID field was gone by default. This is the behavior I was wanting.

Jessiejessika answered 31/5, 2017 at 23:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.