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

Bug: Required foreign key is empty #485

Open
mlachowski opened this issue Jan 22, 2024 · 3 comments
Open

Bug: Required foreign key is empty #485

mlachowski opened this issue Jan 22, 2024 · 3 comments
Labels
bug Something isn't working unconfirmed

Comments

@mlachowski
Copy link

mlachowski commented Jan 22, 2024

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"
@mlachowski mlachowski added the bug Something isn't working label Jan 22, 2024
@hasansezertasan
Copy link
Contributor

Can you provide ModelViews too?

@mlachowski
Copy link
Author

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.

@mlachowski
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working unconfirmed
Projects
None yet
Development

No branches or pull requests

3 participants