@@ -32,6 +32,7 @@ class Person(BaseModel):
3232 serializer = Person .drf_serializer ()
3333
3434 assert isinstance (serializer .fields ["name" ], serializers .CharField )
35+ assert serializer .fields ["name" ].allow_blank is True
3536
3637 def test_constrained_string (self ):
3738 class Person (BaseModel ):
@@ -45,6 +46,7 @@ class Person(BaseModel):
4546 assert isinstance (serializer .fields ["name" ], serializers .CharField )
4647 assert serializer .fields ["name" ].min_length == 3
4748 assert serializer .fields ["name" ].max_length == 10
49+ assert serializer .fields ["name" ].allow_blank is False
4850
4951 def test_constrained_string_defined_from_field (self ):
5052 class Person (BaseModel ):
@@ -55,6 +57,7 @@ class Person(BaseModel):
5557 assert isinstance (serializer .fields ["name" ], serializers .CharField )
5658 assert serializer .fields ["name" ].min_length == 3
5759 assert serializer .fields ["name" ].max_length == 10
60+ assert serializer .fields ["name" ].allow_blank is False
5861
5962 def test_constrained_string_min_max_values (self ):
6063 """Must be ignored in non-numeric fields"""
@@ -87,6 +90,7 @@ class Person(BaseModel):
8790 serializer = Person .drf_serializer ()
8891
8992 assert isinstance (serializer .fields ["email" ], serializers .EmailField )
93+ assert serializer .fields ["email" ].allow_blank is False
9094
9195 def test_regex (self ):
9296 pattern = r"^\+?[0-9]+$"
@@ -156,6 +160,7 @@ class Person(BaseModel):
156160 pattern
157161 )
158162 assert serializer .fields ["phone_number" ].allow_null is True
163+ assert serializer .fields ["phone_number" ].allow_blank is False
159164
160165 def test_multiple_regex_error (self ):
161166 with pytest .raises (ModelConversionError ) as exc_info :
@@ -194,6 +199,7 @@ class Person(BaseModel):
194199 serializer = Person .drf_serializer ()
195200
196201 assert isinstance (serializer .fields ["website" ], serializers .URLField )
202+ assert serializer .fields ["website" ].allow_blank is False
197203
198204 def test_uuid (self ):
199205 class Person (BaseModel ):
@@ -621,6 +627,7 @@ class Person(BaseModel):
621627 field : serializers .Field = serializer .fields ["name" ]
622628 assert isinstance (field , serializers .CharField )
623629 assert field .allow_null is True
630+ assert field .allow_blank is True
624631
625632 def test_optional_type_with_union (self ):
626633 class Person (BaseModel ):
@@ -631,6 +638,7 @@ class Person(BaseModel):
631638 field : serializers .Field = serializer .fields ["name" ]
632639 assert isinstance (field , serializers .CharField )
633640 assert field .allow_null is True
641+ assert field .allow_blank is True
634642
635643 @pytest .mark .skipif (sys .version_info < (3 , 10 ), reason = "Requires Python 3.10+" )
636644 def test_optional_type_with_pipe (self ):
@@ -642,6 +650,7 @@ class Person(BaseModel):
642650 field : serializers .Field = serializer .fields ["name" ]
643651 assert isinstance (field , serializers .CharField )
644652 assert field .allow_null is True
653+ assert field .allow_blank is True
645654
646655 def test_optional_type_with_annotation (self ):
647656 class Person (BaseModel ):
@@ -655,6 +664,7 @@ class Person(BaseModel):
655664 field : serializers .Field = serializer .fields ["name" ]
656665 assert isinstance (field , serializers .CharField )
657666 assert field .allow_null is True
667+ assert field .allow_blank is False
658668
659669 def test_union_field_error (self ):
660670 with pytest .raises (ModelConversionError ) as exc_info :
@@ -725,6 +735,64 @@ class Person(BaseModel):
725735 assert serializer .fields ["field_11" ].label == "11th field"
726736
727737
738+ def test_allow_blank ():
739+ pattern = r"^\+?[0-9]+$"
740+ empty_pattern = r"^$"
741+ compiled_pattern = re .compile (pattern )
742+ compiled_empty_pattern = re .compile (empty_pattern )
743+
744+ class Person (BaseModel ):
745+ field_1 : str
746+ field_2 : typing .Optional [str ]
747+ field_3 : str = pydantic .Field (min_length = 1 )
748+ field_4 : str = pydantic .Field (min_length = 0 )
749+ field_5 : typing .Annotated [str , pydantic .Field (min_length = 1 )]
750+ field_6 : typing .Annotated [str , pydantic .Field (min_length = 0 )]
751+ field_7 : typing .Optional [str ] = pydantic .Field (min_length = 1 )
752+ field_8 : typing .Optional [str ] = pydantic .Field (min_length = 0 )
753+ field_9 : typing .Annotated [typing .Optional [str ], pydantic .Field (min_length = 1 )]
754+ field_10 : typing .Annotated [typing .Optional [str ], pydantic .Field (min_length = 0 )]
755+ field_11 : typing .Annotated [str , pydantic .StringConstraints (min_length = 1 )]
756+ field_12 : typing .Annotated [str , pydantic .StringConstraints (min_length = 0 )]
757+ field_13 : typing .Annotated [str , pydantic .Field (pattern = pattern )]
758+ field_14 : typing .Annotated [str , pydantic .Field (pattern = empty_pattern )]
759+ field_15 : typing .Annotated [str , pydantic .Field (pattern = compiled_pattern )]
760+ field_16 : typing .Annotated [str , pydantic .Field (pattern = compiled_empty_pattern )]
761+ field_17 : typing .Annotated [str , pydantic .StringConstraints (pattern = pattern )]
762+ field_18 : typing .Annotated [
763+ str , pydantic .StringConstraints (pattern = empty_pattern )
764+ ]
765+ field_19 : typing .Annotated [
766+ str , pydantic .StringConstraints (pattern = compiled_pattern )
767+ ]
768+ field_20 : typing .Annotated [
769+ str , pydantic .StringConstraints (pattern = compiled_empty_pattern )
770+ ]
771+
772+ serializer = Person .drf_serializer ()
773+
774+ assert serializer .fields ["field_1" ].allow_blank is True
775+ assert serializer .fields ["field_2" ].allow_blank is True
776+ assert serializer .fields ["field_3" ].allow_blank is False
777+ assert serializer .fields ["field_4" ].allow_blank is True
778+ assert serializer .fields ["field_5" ].allow_blank is False
779+ assert serializer .fields ["field_6" ].allow_blank is True
780+ assert serializer .fields ["field_7" ].allow_blank is False
781+ assert serializer .fields ["field_8" ].allow_blank is True
782+ assert serializer .fields ["field_9" ].allow_blank is False
783+ assert serializer .fields ["field_10" ].allow_blank is True
784+ assert serializer .fields ["field_11" ].allow_blank is False
785+ assert serializer .fields ["field_12" ].allow_blank is True
786+ assert serializer .fields ["field_13" ].allow_blank is False
787+ assert serializer .fields ["field_14" ].allow_blank is True
788+ assert serializer .fields ["field_15" ].allow_blank is False
789+ assert serializer .fields ["field_16" ].allow_blank is True
790+ assert serializer .fields ["field_17" ].allow_blank is False
791+ assert serializer .fields ["field_18" ].allow_blank is True
792+ assert serializer .fields ["field_19" ].allow_blank is False
793+ assert serializer .fields ["field_20" ].allow_blank is True
794+
795+
728796class TestManualFields :
729797 def test_same_type (self ):
730798 class Person (BaseModel ):
0 commit comments