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

feat: allow keep not nullable fields not nullable #32

Closed
wants to merge 3 commits into from

Conversation

ADR-007
Copy link

@ADR-007 ADR-007 commented Apr 10, 2024

Currently, pydantic-partial allows to set None for not nullable fields, which brakes the validate logic on the FastAPI endpoint.

This PR provides a new parameter use_undefined, to use UNDEFINED value as default instead of None, and doesn't make fields nullable.

Please take a look on the test cases.

Use case:

class UserUpdateSchema(PartialModelMixin, pydantic.BaseModel):
    first_name: str
    second_name: str | None
  

@router.put()
def update_me(user: AuthUser, payload: UserUpdateSchema):
    user.set_values(payload.model_dump())

@router.patch()
def partial_update_me(user: AuthUser, payload: UserUpdateSchema.model_as_partial(
    use_undefined=True, # without this flag `first_name` can be set to `None` which is wrong
)):
    user.set_values(payload.model_dump(exclude_unset=True))

@ADR-007
Copy link
Author

ADR-007 commented Apr 10, 2024

Actually, I can have everything I want to using this code snippet:

T = TypeVar("T", bound=BaseModel)


def create_partial_model(
    model: type[T],
    optional_fields: Iterable[str] | None = (),
    default_value: Any = None,
) -> type[T]:
    fields = {}
    for field in optional_fields or model.model_fields.keys():
        field_info = model.model_fields[field]

        fields[field] = (
            field_info.rebuild_annotation(),
            FieldInfo.merge_field_infos(field_info, default=default_value),
        )

    return create_model(
        model.__name__ + "Partial",
        __base__=model,
        **fields,
    )

So, I'll, probably, just create another library.

@ADR-007
Copy link
Author

ADR-007 commented Apr 11, 2024

Here is the solution

@ddanier
Copy link
Member

ddanier commented Apr 22, 2024

Not sure I like the proposed change. It just moves the issue to another value. Also I normally just use pydantic-apply and then apply only the set fields, so you don't need to care about fields being None - as those are still unset.

I will close this PR, as you created a solution in your own package ;-)

@ddanier ddanier closed this Apr 22, 2024
@ddanier
Copy link
Member

ddanier commented Apr 22, 2024

Still many thanks for putting effort into this!

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

Successfully merging this pull request may close these issues.

2 participants