diff --git a/src/drf_pydantic/parse.py b/src/drf_pydantic/parse.py index 5f33e46..eaf7c69 100644 --- a/src/drf_pydantic/parse.py +++ b/src/drf_pydantic/parse.py @@ -11,6 +11,7 @@ import pydantic.fields import pydantic_core +from annotated_types import MaxLen, MinLen from pydantic._internal._fields import PydanticMetadata from rest_framework import serializers # type: ignore from typing_extensions import TypeAliasType @@ -165,6 +166,24 @@ def _convert_field(field: pydantic.fields.FieldInfo) -> serializers.Field: if item.max_length is not None else drf_field_kwargs.get("max_length", None) ) + elif isinstance(item, MinLen): + drf_field_kwargs["min_length"] = ( + max( + drf_field_kwargs.get("min_length", float("-inf")), + item.min_length, + ) + if item.min_length is not None + else drf_field_kwargs.get("min_length", None) + ) + elif isinstance(item, MaxLen): + drf_field_kwargs["max_length"] = ( + min( + drf_field_kwargs.get("max_length", float("inf")), + item.max_length, + ) + if item.max_length is not None + else drf_field_kwargs.get("max_length", None) + ) # pydantic.Field constraints elif isinstance(item, PydanticMetadata): # Decimal constraints diff --git a/tests/test_fields.py b/tests/test_fields.py index 446c2df..38e9d89 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -45,6 +45,25 @@ class Person(BaseModel): assert serializer.fields["name"].min_length == 3 assert serializer.fields["name"].max_length == 10 + def test_constrained_string_defined_from_field(self): + class Person(BaseModel): + name: str = pydantic.Field(min_length=3, max_length=10) + + serializer = Person.drf_serializer() + + assert isinstance(serializer.fields["name"], serializers.CharField) + assert serializer.fields["name"].min_length == 3 + assert serializer.fields["name"].max_length == 10 + + def test_constrained_list(self): + class Person(BaseModel): + name: list[int] = pydantic.Field(min_length=3, max_length=10) + + serializer = Person.drf_serializer() + assert isinstance(serializer.fields["name"], serializers.ListField) + assert serializer.fields["name"].min_length == 3 + assert serializer.fields["name"].max_length == 10 + def test_email(self): class Person(BaseModel): email: pydantic.EmailStr