starlette-admin
starlette-admin copied to clipboard
Bug: Required foreign key is empty
Describe the bug When creating a new entity which has required related model I've got an error.
To Reproduce
class Company(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str
facilities: List["Facility"] = Relationship(back_populates="company")
class Facility(SQLModel, table=True):
id: int = Field(default=None, primary_key=True)
name: str
company_id: int = Field(foreign_key="company.id")
company: Company = Relationship(back_populates="facilities")
During saving the Facility there is an 422 http error and "{'company_id': 'Field required'}" in errors.
Environment (please complete the following information):
- Starlette-Admin version: starlette-admin = {extras = ["i18n"], version = "^0.13.0"}
- ORM/ODMs: SQLModel sqlmodel = "^0.0.14"
Can you provide ModelView
s too?
At the beginning I had custom View with list of excluded fields and other settings but then I tried raw approach without any settings and this error still occurs.
from starlette_admin.contrib.sqlmodel import ModelView
facility_view = ModelView(Facility, icon="fa-solid fa-building")
However following code did the trick for me - I'm copying id from selected object into _id field:
arranged_data[f"{field.name}_id"] = arranged_data[field.name].id
async def _arrange_data(
self,
request: Request,
data: Dict[str, Any],
is_edit: bool = False,
) -> Dict[str, Any]:
"""
This function will return a new dict with relationships loaded from
database.
"""
arranged_data: Dict[str, Any] = {}
for field in self.get_fields_list(request, request.state.action):
if isinstance(field, RelationField) and data[field.name] is not None:
foreign_model = self._find_foreign_model(field.identity) # type: ignore
if not field.multiple:
arranged_data[field.name] = await foreign_model.find_by_pk(
request, data[field.name]
)
arranged_data[f"{field.name}_id"] = arranged_data[field.name].id
else:
arranged_data[field.name] = await foreign_model.find_by_pks(
request, data[field.name]
)
else:
arranged_data[field.name] = data[field.name]
return arranged_data
My guess is that pydantic is unhappy about empty company_id
but still it seems like should be resolved somehow by sqlmodel / data population of starlette admin.
After some more digging it seems like the issue is here:
self.model.validate(...)
Because pydantic expects to have the _id
field during model validation.