diff --git a/django_unicorn/typer.py b/django_unicorn/typer.py index 6b58481f..5a128519 100644 --- a/django_unicorn/typer.py +++ b/django_unicorn/typer.py @@ -6,6 +6,17 @@ from typing import get_type_hints as typing_get_type_hints from uuid import UUID +try: + from pydantic import BaseModel + + def _check_pydantic(cls) -> bool: + return issubclass(cls, BaseModel) +except ImportError: + + def _check_pydantic(cls) -> bool: # noqa: ARG001 + return False + + from django.db.models import Model, QuerySet from django.utils.dateparse import ( parse_date, @@ -13,7 +24,6 @@ parse_duration, parse_time, ) -from pydantic import BaseModel from django_unicorn.typing import QuerySetType @@ -141,9 +151,10 @@ def cast_value(type_hint, value): if issubclass(type_hint, Model): continue - if issubclass(type_hint, BaseModel) or is_dataclass(type_hint): + if _check_pydantic(type_hint) or is_dataclass(type_hint): value = type_hint(**value) break + value = type_hint(value) break diff --git a/tests/serializer/test_dumps.py b/tests/serializer/test_dumps.py index 4f69b591..042a77f6 100644 --- a/tests/serializer/test_dumps.py +++ b/tests/serializer/test_dumps.py @@ -8,6 +8,7 @@ import pytest from django.db import models from django.utils.timezone import now +from pydantic import BaseModel from django_unicorn import serializer from django_unicorn.serializer import InvalidFieldAttributeError, InvalidFieldNameError @@ -698,8 +699,6 @@ def test_nested_list_float_less_complicated(): def test_pydantic(): - from pydantic import BaseModel - class Book(BaseModel): title = "The Grapes of Wrath" author = "John Steinbeck" diff --git a/tests/test_typer.py b/tests/test_typer.py index 4822d429..a7dbd044 100644 --- a/tests/test_typer.py +++ b/tests/test_typer.py @@ -1,5 +1,5 @@ -from dataclasses import dataclass import datetime +from dataclasses import dataclass from typing import List, Optional from typing import get_type_hints as typing_get_type_hints @@ -117,24 +117,24 @@ def test_cast_value_model_int(): @dataclass -class TestDataClass: +class DataClass: name: str -class PydanticDataClass(BaseModel): +class PydanticBaseModel(BaseModel): name: str class AnotherExampleClass: - data: TestDataClass - list_data: List[TestDataClass] - pydantic_data: PydanticDataClass - pydantic_list_data: List[PydanticDataClass] + data: DataClass + list_data: List[DataClass] + pydantic_data: PydanticBaseModel + pydantic_list_data: List[PydanticBaseModel] def test_cast_value_dataclass(): example_class = AnotherExampleClass() - test_data = TestDataClass(name="foo") + test_data = DataClass(name="foo") example_class.data = test_data type_hints = typing_get_type_hints(example_class) type_hint = type_hints["data"] @@ -144,7 +144,7 @@ def test_cast_value_dataclass(): def test_cast_value_pydantic(): example_class = AnotherExampleClass() - test_data = PydanticDataClass(name="foo") + test_data = PydanticBaseModel(name="foo") example_class.pydantic_data = test_data type_hints = typing_get_type_hints(example_class) type_hint = type_hints["pydantic_data"] @@ -154,7 +154,7 @@ def test_cast_value_pydantic(): def test_cast_value_list_dataclass(): example_class = AnotherExampleClass() - test_data = TestDataClass(name="foo") + test_data = DataClass(name="foo") example_class.pydantic_list_data = [test_data] type_hints = typing_get_type_hints(example_class) type_hint = type_hints["list_data"] @@ -164,7 +164,7 @@ def test_cast_value_list_dataclass(): def test_cast_value_list_pydantic(): example_class = AnotherExampleClass() - test_data = PydanticDataClass(name="foo") + test_data = PydanticBaseModel(name="foo") example_class.pydantic_list_data = [test_data] type_hints = typing_get_type_hints(example_class) type_hint = type_hints["pydantic_list_data"]