Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ItemsRequired validator AttributeError: 'QuerySelectMultipleField' object has no attribute 'entries' #2385

Open
thaddeusmt opened this issue Oct 4, 2023 · 0 comments
Labels

Comments

@thaddeusmt
Copy link

There might a new bug introduced between v1.6.0 and v1.6.1.

This is the stacktrace of the error:

2023-10-03 14:28:17 ERROR:app.main:Exception on /admin/a/edit/ [POST]
...
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask/app.py", line 1523, in full_dispatch_request
2023-10-03 14:28:17     rv = self.dispatch_request()
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask/app.py", line 1509, in dispatch_request
2023-10-03 14:28:17     return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask_admin/base.py", line 69, in inner
2023-10-03 14:28:17     return self._run_view(f, *args, **kwargs)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask_admin/base.py", line 369, in _run_view
2023-10-03 14:28:17     return fn(self, *args, **kwargs)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask_admin/model/base.py", line 2153, in edit_view
2023-10-03 14:28:17     if self.validate_form(form):
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask_admin/model/base.py", line 1382, in validate_form
2023-10-03 14:28:17     return validate_form_on_submit(form)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask_admin/helpers.py", line 71, in validate_form_on_submit
2023-10-03 14:28:17     return is_form_submitted() and form.validate()
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/wtforms/form.py", line 329, in validate
2023-10-03 14:28:17     return super().validate(extra)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/wtforms/form.py", line 146, in validate
2023-10-03 14:28:17     if not field.validate(self, extra):
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/wtforms/fields/core.py", line 242, in validate
2023-10-03 14:28:17     stop_validation = self._run_validation_chain(form, chain)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/wtforms/fields/core.py", line 262, in _run_validation_chain
2023-10-03 14:28:17     validator(form, self)
2023-10-03 14:28:17   File "/root/.cache/pypoetry/virtualenvs/app-gW_DSdP6-py3.10/lib/python3.10/site-packages/flask_admin/contrib/sqla/validators.py", line 60, in __call__
2023-10-03 14:28:17     items = filter_list(lambda e: not field.should_delete(e), field.entries)
2023-10-03 14:28:17 AttributeError: 'QuerySelectMultipleField' object has no attribute 'entries'

Essentially our form has a QuerySelectMultipleField called port_standards with a ItemsRequired(min=1) validator that is throwing the error above.

In the sqla.ModelView we have a validator declared this way:

from flask_admin.contrib.sqla import ModelView
from flask_admin.contrib.sqla.validators import ItemsRequired
class OurView(ModelView):
    ....
    form_args = dict(
        port_standards=dict(validators=[ItemsRequired(min=1)]),
    )

Here are (simplified) the SqlAlchemy models related to the port_standards field where the issue is:

class PortStandard(BaseModel):
   """The PortStandard table"""
    __tablename__ = "PortStandard"
    id = sa.Column(sa.Integer, primary_key=True)
    name = sa.Column(sa.Enum(PortStandardEnum), unique=True, nullable=False)
    description = sa.Column(sa.Text)
    port_standard_a: List[“APortStandard"] = relationship(
        “APortStandard",
        back_populates="port_standard",
        cascade="all, delete-orphan",
    )
    As: List["A"] = association_proxy(
        "port_standard_a",
        "A",
        creator=make_creator("APortStandard", "a"),
    )

class APortStandard(BaseModel):
   """A many-to-many relationship mapping table between PortStandard and A"""
    __tablename__ = "APortStandard"
    a_id = sa.Column(sa.Integer, sa.ForeignKey("A.id"), primary_key=True)
    a: "A" = relationship("A", back_populates="a_port_standards")
    port_standard_id = sa.Column(
        sa.Integer, sa.ForeignKey("PortStandard.id"), primary_key=True
    )
    port_standard: "PortStandard" = relationship(
        "PortStandard", back_populates="port_standard_a”
    )

class A(BaseModel):
    """The A model table, which can have multiple PortStandards"""
    ...
    a_port_standards: List["APortStandard"] = relationship(
        “APortStandard",
        back_populates="a",
        cascade="all, delete-orphan",
    )
    # NOTE: this is the QuerySelectMultipleField relationship being validated in the flask-admin form
    port_standards: List["PortStandard"] = association_proxy(
        "a_port_standards",
        "port_standard",
        creator=make_creator(“APortStandard", "port_standard"),
    )

The change that is causing the error looks like it was introduced in this commit:
cb46417#diff-bf770a0ad6b3918a287619c4af8e70500738b9fdebee7f584d9b25df64cd3263R60

Whatever type the field is, in the ItemsRequired validator, it doesn't have the entries property.
This code was working in v.1.6.0 and now has this error when we upgraded to v.1.6.1.

I am sorry I don't have time at the moment to look in to a bugfix to contribute back. Our solution for now is to continue to use v1.6.0. I'm just logging the bug in case this helps anyone else debugging a similar issue in the future.

Thanks to everyone who works on this wonderful project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

2 participants