From bb9b39ab4c597196d1e43ad64a8355e05a0f39fa Mon Sep 17 00:00:00 2001 From: Savva Surenkov Date: Sun, 5 May 2024 22:53:28 +0400 Subject: [PATCH] Bypass field validation on model instantiation if it does not contain a default= argument --- Makefile | 17 ++++++++++++++--- django_pydantic_field/v1/fields.py | 4 +++- django_pydantic_field/v2/fields.py | 9 ++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 739be3a..9af5098 100644 --- a/Makefile +++ b/Makefile @@ -1,34 +1,45 @@ - DJANGO_SETTINGS_MODULE ?= "tests.settings.django_test_settings" - -.PHONY: install build test lint upload upload-test clean +export DJANGO_SETTINGS_MODULE=tests.settings.django_test_settings +.PHONY: install install: python3 -m pip install build twine python3 -m pip install -e .[dev,test] +.PHONY: build build: python3 -m build +.PHONY: migrations migrations: python3 -m django makemigrations --noinput +.PHONY: runserver runserver: python3 -m django migrate && \ python3 -m django runserver +.PHONY: check +check: + python3 -m django check + +.PHONY: test test: A= test: pytest $(A) +.PHONY: lint lint: A=. lint: python3 -m mypy $(A) +.PHONY: upload upload: python3 -m twine upload dist/* +.PHONY: upload-test upload-test: python3 -m twine upload --repository testpypi dist/* +.PHONY: clean clean: rm -rf dist/* diff --git a/django_pydantic_field/v1/fields.py b/django_pydantic_field/v1/fields.py index 24a7af0..66b7947 100644 --- a/django_pydantic_field/v1/fields.py +++ b/django_pydantic_field/v1/fields.py @@ -34,7 +34,9 @@ def contribute_to_class(self, cls, name, *args, **kwargs): field: "PydanticSchemaField" def __set__(self, obj, value): - obj.__dict__[self.field.attname] = self.field.to_python(value) + if self.field.has_default() or value is not None: + value = self.field.to_python(value) + obj.__dict__[self.field.attname] = value class PydanticSchemaField(JSONField, t.Generic[base.ST]): diff --git a/django_pydantic_field/v2/fields.py b/django_pydantic_field/v2/fields.py index 7113342..72c9ef0 100644 --- a/django_pydantic_field/v2/fields.py +++ b/django_pydantic_field/v2/fields.py @@ -60,11 +60,13 @@ def __set_name__(self, owner, name): self.field.adapter.bind(owner, name) def __set__(self, obj, value): - obj.__dict__[self.field.attname] = self.field.to_python(value) + if self.field.has_default() or value is not None: + value = self.field.to_python(value) + obj.__dict__[self.field.attname] = value class PydanticSchemaField(JSONField, ty.Generic[types.ST]): - descriptor_class: type[DeferredAttribute] = SchemaAttribute + descriptor_class: ty.ClassVar[type[DeferredAttribute]] = SchemaAttribute adapter: types.SchemaAdapter def __init__( @@ -118,7 +120,8 @@ def check(self, **kwargs: ty.Any) -> list[checks.CheckMessage]: try: # Test that the default value conforms to the schema. - self.get_prep_value(self.get_default()) + if self.has_default(): + self.get_prep_value(self.get_default()) except pydantic.ValidationError as exc: message = f"Default value cannot be adapted to the schema. Pydantic error: \n{str(exc)}" performed_checks.append(checks.Error(message, obj=self, id="pydantic.E002"))