Flask-AppBuilder icon indicating copy to clipboard operation
Flask-AppBuilder copied to clipboard

show, edit and delete on view returns 404 on modelview with model that inherits from dict

Open befuhro opened this issue 2 years ago • 5 comments

Environment

Flask-Appbuilder version: 4.1.6

pip freeze output:

alembic==1.8.1
apispec==3.3.2
attrs==22.1.0
Babel==2.11.0
certifi==2022.12.7
charset-normalizer==2.1.1
click==8.1.3
colorama==0.4.6
dnspython==2.2.1
email-validator==1.3.0
Flask==2.2.2
Flask-AppBuilder==4.1.6
Flask-Babel==2.0.0
Flask-JWT-Extended==4.4.4
Flask-Login==0.6.2
Flask-Migrate==4.0.0
Flask-SQLAlchemy==2.5.1
Flask-WTF==1.0.1
greenlet==2.0.1
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
jsonschema==4.17.3
Mako==1.2.4
MarkupSafe==2.1.1
marshmallow==3.19.0
marshmallow-enum==1.5.1
marshmallow-sqlalchemy==0.26.1
packaging==22.0
prison==0.2.1
PyJWT==2.6.0
pyrsistent==0.19.2
python-dateutil==2.8.2
pytz==2022.6
PyYAML==6.0
requests==2.28.1
six==1.16.0
SQLAlchemy==1.4.45
SQLAlchemy-Utils==0.38.3
urllib3==1.26.13
Werkzeug==2.2.2
WTForms==3.0.1

Describe the expected results

I would like to be able to show, edit or delete the resources from this model inside the GUI

class Company(Model, dict):
    """ Tag """
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True, nullable=False)
    code_name = Column(String(10), unique=True, nullable=False)
    subscription_expiration = Column(Date(), nullable=False)

    tags = relationship(
        "Tag", secondary=association_company_tag_table, backref="companies")
    employees = relationship("Recipient", back_populates="company", cascade="all, delete-orphan")


    def __repr__(self):
        return self.name

Describe the actual results

When I try to show, edit or delete a model that inherits from dict it returns a 404 with a valid pk

image image image image image

Steps to reproduce

Using the model above in a model view

Solution

On the BaseCRUDView class (file baseviews.py: L1185, L1239 and L1294) The checking for existing record is done like this

item = self.datamodel.get(pk, self._base_filters)
if not item:
    abort(404)

By doing it this way, it is working and does not abort with my model

item = self.datamodel.get(pk, self._base_filters)
if item is None:
    abort(404)

Was the first way implemented purposely or is it possible to make pull request to fix this issue? Thank you for your time

befuhro avatar Dec 14 '22 15:12 befuhro

you probably mean:

if item is None:
    abort(404)

ThomasP0815 avatar Dec 14 '22 19:12 ThomasP0815

you probably mean:

if item is None:
    abort(404)

Yes my bad

befuhro avatar Dec 14 '22 21:12 befuhro

seems like a valid fix, interesting is it because the used dunder method __bool __ is from dict?

Feel free to PR

dpgaspar avatar Dec 16 '22 14:12 dpgaspar

I could not really play with dict as it is a builtin so I dont really know I can't create a branch on the repo, could you give access to it so I can do the PR?

befuhro avatar Dec 19 '22 09:12 befuhro

  1. fork the repo 'dpgaspar/Flask-AppBuilder'
  2. create a branch
  3. create a pull request from the new branch to the master of 'dpgaspar/Flask-AppBuilder'

ThomasP0815 avatar Jan 03 '23 11:01 ThomasP0815