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

option to set validators of pydantic model #1471

Merged
merged 3 commits into from
Nov 5, 2023

Conversation

lucasbrahm
Copy link
Contributor

@lucasbrahm lucasbrahm commented Aug 30, 2023

Pydantic provides Before, After, Wrap and Plain validators, Field validators and Model validators. This is nice for cleaning and validating fields. For example, you can remove any non numeric characters for a phone field and then validate, like this:

class Register(BaseModel):
    phone: str
    
    @field_validator('phone')
    @classmethod
    def validate_phone(cls, v: str) -> str:
        new_phone = re.sub(r'\D', '', v)
        if len(new_phone) < 7:
            raise ValueError('Invalid phone number')
        return new_phone

So both phone '123-4567' and '1234567' will be validated and it will be stored as '1234567'.

The problem of tortoise "pydantic_model_creator" is that it exposes few options when calling pydantic "create_model". Also, tortoise field validators only validate data, without modifying/cleaning data.

Fortunately, you can add validators in pyndatic by passing a dict to the "validators" argument when calling "create_model".

The idea of this PR is to add "validators" option in tortoise "pydantic_model_creator" which will be used during the call of pydantic "create_model"

So in the end it would be like this:

class Register(models.Model):
    phone = fields.CharField(max_length=20)
    

def validate_phone(v: str) -> str:
    new_phone = re.sub(r'\D', '', v)
    if len(new_phone) < 7:
        raise ValueError('Invalid phone number')
    return new_phone

validators = {
    'phone_validator': field_validator('phone')(validate_phone)
}

Register_Pydantic = pydantic_model_creator(Register, name="Register", __validators__=validators)

@@ -131,6 +131,7 @@ def pydantic_model_creator(
exclude_readonly: bool = False,
meta_override: Optional[Type] = None,
model_config: Optional[ConfigDict] = None,
__validators__: dict[str, Any] | None = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO this should be received as validators (without the underscores at beginning and end).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so.

@@ -131,6 +131,7 @@ def pydantic_model_creator(
exclude_readonly: bool = False,
meta_override: Optional[Type] = None,
model_config: Optional[ConfigDict] = None,
__validators__: dict[str, Any] | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so.

@long2ice
Copy link
Member

long2ice commented Nov 3, 2023

Also please update changlog.

@lucasbrahm
Copy link
Contributor Author

Made the adjustments. Also updated the docstring.
Not sure how to add it to the changelog

@long2ice
Copy link
Member

long2ice commented Nov 4, 2023

Just ref CHANGELOG.rst

@lucasbrahm
Copy link
Contributor Author

Is it ok?

@long2ice
Copy link
Member

long2ice commented Nov 5, 2023

Thanks!

@long2ice long2ice merged commit 0ec208b into tortoise:develop Nov 5, 2023
5 checks passed
@coveralls
Copy link

Pull Request Test Coverage Report for Build 6756606059

Warning: This coverage report may be inaccurate.

We've detected an issue with your CI configuration that might affect the accuracy of this pull request's coverage report.
To ensure accuracy in future PRs, please see these guidelines.
A quick fix for this PR: rebase it; your next report should be accurate.

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 88.67%

Totals Coverage Status
Change from base Build 6502900700: 0.0%
Covered Lines: 5756
Relevant Lines: 6408

💛 - Coveralls

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.

5 participants