@@ -664,49 +664,32 @@ print(type(post.content))
664
664
# OUTPUT: Article
665
665
# Article is very inclusive and all fields are optional, allowing any dict to become valid
666
666
```
667
- ** Not Terrible Solutions:**
668
- 1 . Order field types properly: from the most strict ones to loose ones.
667
+ ** Solutions:**
668
+ 1 . Validate input has only valid fields
669
669
``` python
670
- class Post (BaseModel ):
671
- content: Video | Article
672
- ```
673
- 2 . Validate input has only valid fields
674
- ``` python
675
- from pydantic import BaseModel, root_validator
670
+ from pydantic import BaseModel, Extra, root_validator
676
671
677
672
class Article (BaseModel ):
678
673
text: str | None
679
674
extra: str | None
680
675
681
- @root_validator (pre = True ) # validate all values before pydantic
682
- def has_only_article_fields (cls , data : dict ):
683
- """ Silly and ugly solution to validate data has only article fields."""
684
- fields = set (data.keys())
685
- if fields != {" text" , " extra" }:
686
- raise ValueError (" invalid fields" )
687
-
688
- return data
676
+ class Config :
677
+ extra = Extra.forbid
689
678
690
679
691
680
class Video (BaseModel ):
692
681
video_id: int
693
682
text: str | None
694
683
extra: str | None
695
684
696
- @root_validator (pre = True )
697
- def has_only_video_fields (cls , data : dict ):
698
- """ Silly and ugly solution to validate data has only video fields."""
699
- fields = set (data.keys())
700
- if fields != {" text" , " extra" , " video_id" }:
701
- raise ValueError (" invalid fields" )
702
-
703
- return data
685
+ class Config :
686
+ extra = Extra.forbid
704
687
705
688
706
689
class Post (BaseModel ):
707
690
content: Article | Video
708
691
```
709
- 3 . Use Pydantic's Smart Union (>v1.9) if fields are simple
692
+ 2 . Use Pydantic's Smart Union (>v1.9) if fields are simple
710
693
711
694
It's a good solution if the fields are simple like ` int ` or ` bool ` ,
712
695
but it doesn't work for complex fields like classes.
@@ -748,6 +731,16 @@ print(type(p.field_2))
748
731
print (type (p.content))
749
732
# OUTPUT: Article, because smart_union doesn't work for complex fields like classes
750
733
```
734
+
735
+ ** Fast Workaround:**
736
+
737
+ Order field types properly: from the most strict ones to loose ones.
738
+
739
+ ``` python
740
+ class Post (BaseModel ):
741
+ content: Video | Article
742
+ ```
743
+
751
744
### 19. SQL-first, Pydantic-second
752
745
- Usually, database handles data processing much faster and cleaner than CPython will ever do.
753
746
- It's preferable to do all the complex joins and simple data manipulations with SQL.
0 commit comments