Replace custom field validators with Extra.forbid by @anton-shum
This commit is contained in:
43
README.md
43
README.md
@@ -664,28 +664,17 @@ print(type(post.content))
|
||||
# OUTPUT: Article
|
||||
# Article is very inclusive and all fields are optional, allowing any dict to become valid
|
||||
```
|
||||
**Not Terrible Solutions:**
|
||||
1. Order field types properly: from the most strict ones to loose ones.
|
||||
**Solutions:**
|
||||
1. Validate input has only valid fields
|
||||
```python
|
||||
class Post(BaseModel):
|
||||
content: Video | Article
|
||||
```
|
||||
2. Validate input has only valid fields
|
||||
```python
|
||||
from pydantic import BaseModel, root_validator
|
||||
from pydantic import BaseModel, Extra, root_validator
|
||||
|
||||
class Article(BaseModel):
|
||||
text: str | None
|
||||
extra: str | None
|
||||
|
||||
@root_validator(pre=True) # validate all values before pydantic
|
||||
def has_only_article_fields(cls, data: dict):
|
||||
"""Silly and ugly solution to validate data has only article fields."""
|
||||
fields = set(data.keys())
|
||||
if fields != {"text", "extra"}:
|
||||
raise ValueError("invalid fields")
|
||||
|
||||
return data
|
||||
class Config:
|
||||
extra = Extra.forbid
|
||||
|
||||
|
||||
class Video(BaseModel):
|
||||
@@ -693,20 +682,14 @@ class Video(BaseModel):
|
||||
text: str | None
|
||||
extra: str | None
|
||||
|
||||
@root_validator(pre=True)
|
||||
def has_only_video_fields(cls, data: dict):
|
||||
"""Silly and ugly solution to validate data has only video fields."""
|
||||
fields = set(data.keys())
|
||||
if fields != {"text", "extra", "video_id"}:
|
||||
raise ValueError("invalid fields")
|
||||
|
||||
return data
|
||||
class Config:
|
||||
extra = Extra.forbid
|
||||
|
||||
|
||||
class Post(BaseModel):
|
||||
content: Article | Video
|
||||
```
|
||||
3. Use Pydantic's Smart Union (>v1.9) if fields are simple
|
||||
2. Use Pydantic's Smart Union (>v1.9) if fields are simple
|
||||
|
||||
It's a good solution if the fields are simple like `int` or `bool`,
|
||||
but it doesn't work for complex fields like classes.
|
||||
@@ -748,6 +731,16 @@ print(type(p.field_2))
|
||||
print(type(p.content))
|
||||
# OUTPUT: Article, because smart_union doesn't work for complex fields like classes
|
||||
```
|
||||
|
||||
**Fast Workaround:**
|
||||
|
||||
Order field types properly: from the most strict ones to loose ones.
|
||||
|
||||
```python
|
||||
class Post(BaseModel):
|
||||
content: Video | Article
|
||||
```
|
||||
|
||||
### 19. SQL-first, Pydantic-second
|
||||
- Usually, database handles data processing much faster and cleaner than CPython will ever do.
|
||||
- It's preferable to do all the complex joins and simple data manipulations with SQL.
|
||||
|
||||
Reference in New Issue
Block a user