Flask-AppBuilder: related_views not loading in widgets['related_views'] but does load in related views

I am having a problem working with related views. An Event has many Attendees. You can see a snapshot of the models here:


class Attendee(db.Model):
    __bind_key__ = 'WILL_DB'
    __tablename__ = 'attendee'

    id = Column(INTEGER, primary_key=True)
    event_id = Column(INTEGER, index=True)
    ...

    Event = relationship('Event', primaryjoin="Attendee.event_id == foreign(Event.id)")


class Event(db.Model):
    __bind_key__ = 'WILL_DB'
    __tablename__ = 'event'

    id = Column(INTEGER, primary_key=True)
    rep_id = Column(String(50), nullable=False, server_default=text("''"))
    ...

My view functions are as follows


class AttendeeView(ModelView):
    datamodel = SQLAInterface(Attendee)
    list_columns = [x.name for x in Attendee.__table__.columns]
    list_columns.remove("signature")
    list_columns.remove("hcp_data")

    show_columns = [x.name for x in Attendee.__table__.columns]
    show_columns.remove("signature")
    show_columns.remove("hcp_data")


class EventView(ModelView):
    datamodel = SQLAInterface(Event)
    related_views = [AttendeeView]
    show_template = 'appbuilder/general/model/show_cascade.html'

…and registering:

appbuilder.add_view(
    EventView,
    "Events",
    icon="fa-calendar",
    category="WILL Support",
    category_icon="fa-wheelchair"
)
appbuilder.add_view(
    AttendeeView,
    "Attendees",
    icon="fa-user",
    category="WILL Support",
    category_icon="fa-wheelchair"
)

When navigating to a /eventview/show/10 page for example, I get this output

  File "<project_root>/app/templates/appbuilder/general/model/show_cascade.html", line 15, in template
    {{ widgets.get('related_views')[loop.index - 1](pk = pk)|safe }}
TypeError: 'NoneType' object is not callable

When debugging it seems that in this block which in in the file show_cascade.html and similarly in the other show htmls files.

{% block related_views %}
    {% if related_views is defined %}
        {% for view in related_views %}
            {% call lib.accordion_tag(view.__class__.__name__,view.title, False) %}
                {{ widgets.get('related_views')[loop.index - 1](pk = pk)|safe }}
            {% endcall %}
        {% endfor %}
    {% endif %}
{% endblock related_views %}

The variable related_views contains the appropriate AttendeeView however, widgets['related_views'] has nothing.

Is there an issue with my relationship? This is an old database that doesn’t have the correct key setups so I need to do the relationship this way : Event = relationship('Event', primaryjoin="Attendee.event_id == foreign(Event.id)")

Same data as this issue #973

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 19 (12 by maintainers)

Most upvoted comments

Copying the DB and adding the ForeignKey Constraints fixed the problem.

class Attendee(db.Model):
    __bind_key__ = 'WILL_DB'
    __tablename__ = 'attendee'

    id = Column(INTEGER, primary_key=True)
    event_id = Column(ForeignKey(u'event.id'), index=True)
    ...
    Event = relationship('Event')
  

Im confused on how this is an issue though. I guess using the primaryjoin param when creating the relationship doesn’t set the relationship type correctly?

And here is saying the direction is ONETOMANY which is why it is failing.

        try:
            if self.is_relation(col_name):
                return self.list_properties[col_name].direction.name == "MANYTOONE"
        except Exception:
            return False

Does _get_related_view_widget not support ONETOMANY ?