flask-admin marks db.relationship fields of model views as required, so there is no way to add a record if the table to which relationship goes is empty.
Example:
class Type(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True, index=True)
area_id = db.Column(db.Integer, db.ForeignKey("area.id", onupdate='CASCADE', ondelete='CASCADE'), nullable=False, index=True)
description = db.Column(db.Text)
class Area(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True, index=True)
description = db.Column(db.Text)
types = db.relationship('Type', backref='Area', lazy='dynamic', cascade='all, delete-orphan')
types field is required during creation of area record through flask-admin, but If type table is empty, there is no way to add any information to the database. flask-admin wouldn't allow to add anything to Area table because of backref to Type table which makes the field required, but there is nothing in Type table yet. flask-admin wouldn't allow to add anything to Area table as well, because the field types is required on the page.
I couldn't find anything on the subject. There are some topics discussing workarounds for many-to-many relationships, but this is the simplest one-to-many relationship which to my understanding should just work out of the box.
I figured out that if I add Type to inline_models under Area model then I will see a button "Add Types" on create Area page, but if the inline_model itself has a relationship then that wouldn't help either, because of the same reason.
class ModelViewArea(ModelView):
inline_models = ( models.Type, )
admin.add_view(ModelViewProductArea (models.Area, db.session, name="Area", category='Product'))
admin.add_view(ModelViewProductType (models.Type, db.session, name="Type", category='Product'))
It turned out that if a foreign key associated with the relationship has nullable=False then flask-admin marks the field as required in flask-wtf. Once I removed nullable=False from attributes of the foreign key of Type class, flask-admin stopped showing the field as required in both Type model view and Area model view.
However, as I removed nullable=False there was no more reason for ondelete="CASCADE" and cascade behavior on relationship. Default cascade suits better. The final code looks like:
class Type(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True, index=True)
area_id = db.Column(db.Integer, db.ForeignKey("area.id", onupdate='CASCADE', ondelete='SET NULL'), index=True)
description = db.Column(db.Text)
class Area(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True, index=True)
description = db.Column(db.Text)
types = db.relationship('Type', backref='Area', lazy='dynamic')