Skip to content

Releases: surenkov/django-pydantic-field

Enfoced null checks for `SchemaField`

14 Sep 14:42

Choose a tag to compare

Pre-release

Enforced null checks for SchemaField

In the example below, typing linters should enforce type compatibility:

class BuildingMeta(pydantic.BaseModel):
    type: Optional[BuildingTypes]

class Building(models.Model):
    opt_meta: BuildingMeta = SchemaField(default={"type": "frame"}, null=True)
    meta: Optional[BuildingMeta] = SchemaField(default={"type": "frame"})

Pyright will complain on both fields:

sample_app/models.py:5:32 - error: Expression of type "BuildingMeta | None" cannot be assigned to declared type "BuildingMeta"
sample_app/models.py:6:40 - error: Expression of type "ST@SchemaField" cannot be assigned to declared type "BuildingMeta | None"

Mypy has more broaden resolution for latter check, but still be able to recognise first one:

sample_app/models.py:5: error: Incompatible types in assignment (expression has type "Optional[BuildingMeta]", variable has type "BuildingMeta")

Fixing field annotations will resolve issues on both checkers:

class Building(models.Model):
    opt_meta: Optional[BuildingMeta] = SchemaField(default={"type": "frame"}, null=True)
    meta: BuildingMeta = SchemaField(default={"type": "frame"})

The check also enforces default=None to have null=True param.

Relaxed restrictions on default= argument

In addition to null enforcement, typing checks allow arbitrary values for default= argument, as long as they are acceptable for pydantic's BaseModel.parse_obj method. Callables are also accepted, mimicking Django's field semantics.

Full Changelog: v0.1.10...v0.1.11

v0.1.10

13 Sep 21:22

Choose a tag to compare

v0.1.10 Pre-release
Pre-release

Slightly improve inheritance chain, better typings for SchemaField factory function.

Full Changelog: v0.1.9...v0.1.10

Support for deferred type annotations

13 Sep 14:55

Choose a tag to compare

Pre-release

What's Changed

  • Attempt to defer ForwardRefs resolution by @surenkov in #5

Full Changelog: v0.1.8...v0.1.9

Raise correct exception type on model field validation

13 Sep 09:53

Choose a tag to compare

Django model fields are required to throw django.core.exceptions.ValidationError during .to_python(value) call.
Let's stick to that recommendation.

Convert the input value into the expected Python data type, raising
django.core.exceptions.ValidationError if the data can't be converted.

Make DRF's serializer SchemaField aware of `allow_null` attribute

12 Sep 21:43

Choose a tag to compare

v0.1.7

Make rest_framework.SchemaField aware of `allow_null` attribute

Simplify field error handling

12 Sep 21:23

Choose a tag to compare

Pre-release

I believe that initially introduced error_handler= param is basically doesn't make sense, as it breaks regular validation flow and could be even harmful, as by default it simply suppress errors and writes them in logging. (Re)raising validation errors would be more explicit alternative to that.

Consider raw config dict as a valid `config=` param

12 Sep 17:40

Choose a tag to compare

I feel it's an overhead to define a full Config class in some cases, like:

class Config:
    json_encoders = ...

field: t.List[Schema] = SchemaField(config=Config)

The convenient solution is to pass a dict config instead:

field: t.List[Schema] = SchemaField(config={"json_encoders": ...})

Well, it is now possible to do so.

Explicitly state forward refs resolution behavior

12 Sep 16:46

Choose a tag to compare

I'm considering current behavior with forward references resolution as expected. I.e. field schemas should be always defined before field declaration, otherwise it's not possible to bind a schema to the field during model initialzation. Note though, that annotation should still be declared as string/typing.ForwardRef, as long as prior constraint is satisfied. Main change: now such behavior is explicitly stated with tests.

Downgrade deferred annotations support

09 Sep 10:01

Choose a tag to compare

Pre-release

I tried to defer schema initialzation at a field descriptor level, but this approach did not succeeded with current migrations flow

Support of direct model annotations

07 Sep 16:24

Choose a tag to compare

Pre-release

Now, instead specifying explicit schema, one could write:

from django.db import Model
from django_pydantic_field import SchemaField

class MyModel(models.Model):
    field: list[int] = SchemaField()

The schema will be inferred at model freezing step.
Note that it's not possible to specify unresolved forward references at the moment.