diff --git a/starlette_admin/contrib/sqla/view.py b/starlette_admin/contrib/sqla/view.py index 84d6a377..6bc13587 100644 --- a/starlette_admin/contrib/sqla/view.py +++ b/starlette_admin/contrib/sqla/view.py @@ -95,7 +95,7 @@ def __init__( if self.fields is None or len(self.fields) == 0: self.fields = [ self.model.__dict__[f].key - for f in self.model.__dict__ + for f in list(self.model.__dict__.keys()) if type(self.model.__dict__[f]) is InstrumentedAttribute ] self.fields = (converter or ModelConverter()).convert_fields_list( @@ -134,7 +134,7 @@ def _setup_primary_key(self) -> None: Tuple[InstrumentedAttribute, ...], InstrumentedAttribute ] = () self._pk_coerce: Union[Tuple[type, ...], type] = () - for key in self.model.__dict__: + for key in list(self.model.__dict__.keys()): attr = getattr(self.model, key) if isinstance(attr, InstrumentedAttribute) and getattr( attr, "primary_key", False diff --git a/tests/sqla/test_sync_engine.py b/tests/sqla/test_sync_engine.py index c8e6f1af..51fd56e0 100644 --- a/tests/sqla/test_sync_engine.py +++ b/tests/sqla/test_sync_engine.py @@ -20,6 +20,7 @@ select, ) from sqlalchemy.engine import Engine +from sqlalchemy.ext.associationproxy import association_proxy from sqlalchemy.orm import Session, declarative_base, relationship from sqlalchemy_file.storage import StorageManager from starlette.applications import Starlette @@ -60,6 +61,8 @@ class User(Base): name = Column(String(100), primary_key=True) files = Column(sf.FileField(multiple=True)) products = relationship("Product", back_populates="user") + # to reproduce https://github.com/jowilf/starlette-admin/issues/507 + product_titles = association_proxy("products", "titles") class ProductView(ModelView):