Skip to main content

A clean and simple serialization tool for Django models using Pydantic 2.

Project description

PyDReF - Serializers

Description

This library contains a set of tools to help you create simple serializers for Django models. It was inspired by the Django REST Framework and Pydantic projects.

Motivation

The main motivation for creating this library was to have a simple and easy to use tool to serialize Django models. The library is designed to be used in projects where you need to serialize Django models, but you don't want to use the Django REST Framework.

DRF is a great tool, but it is not always necessary to use it. For example, if you need to create a simple API for a small project, you can use this library instead of the DRFfor the serialization of your models.

Also, though DRF is a great tool, I've never enjoy the heavy responsibility added to its Serializers. Pydantic keeps this simplicity, where the serializers (Pydantic models) are just a simple class that you can use to serialize your data.

Installation

You can install this library using pip:

pip install pydref-serializers

Usage

Creating a serializer class

For creating a serializer for a Django model, you can use the ModelSerializerBuilder class. This class will create a Pydantic model based on the Django model that you pass to it.

from pydref_serializers import ModelSerializerBuilder
from myapp.models import MyModel

MyModelSerializer = ModelSerializerBuilder.from_model_class(MyModel)

The builder will return a class created based on the specified model. If you want to set the fields to be added to the serializer, you can specify them during the creation of the serializer, using the kwargs include_fields or exclude_fields:

from pydref_serializers import ModelSerializerBuilder
from myapp.models import MyModel

MyModelSerializer = ModelSerializerBuilder.from_model_class(
    MyModel,
    include_fields=['field1', 'field2', 'field3'],
    # exclude_fields=['field1', 'field2', 'field3'],
)

The ModelSerializerBuilder also has a few kwargs for configuration how the builder get the fields from the Django model, and also how it maps the fields to the Pydantic model fields.

from pydref_serializers import ModelSerializerBuilder
from myapp.models import MyModel


_FieldMapper = Callable[[DjangoField], tuple[type, Any]]
_FieldGetter = Callable[[type[DjangoModel], Collection[str] | None, Collection[str] | None], dict[type, Any]]

MyModelSerializer = ModelSerializerBuilder.from_model_class(
    MyModel,
    ..., # include_fields or exclude_fields
    fields_getter:_FieldGetter = ...,
    field_mapper:_FieldMapper = ...,
)

Using the serializer

For using the serializer, you can use it as a normal Pydantic model, passing the fields to be serialized as kwargs to the constructor:

from myapp.serializers import MyModelSerializer

serializer = MyModelSerializer(
    field1='value1',
    field2='value2',
    field3='value3',
)

The serializer will validate the fields based on the validators created during the Django Fields to Pydantic annotations mapping.

You can also use the serializer to serialize a Django model instance:

from myapp.serializers import MyModelSerializer
from myapp.models import MyModel

my_model_instance = MyModel.objects.get(pk=1)
serializer = MyModelSerializer.from_model(my_model_instance)

The class method from_model will create a serializer instance based on the Django model instance passed to it. It will convert the model to dict using the django utility model_to_dict located at django.forms.models, and then it will pass the dict to the serializer constructor. You can change this behavior passing a custom function to the model_to_dict kwarg of the from_model method:

from myapp.serializers import MyModelSerializer
from myapp.models import MyModel

my_model_instance = MyModel.objects.get(pk=1)
serializer = MyModelSerializer.from_model(
    my_model_instance,
    model_to_dict=lambda model_instance: model_instance.to_dict(),
)

Field mapping

Fields are transformed based on the following rules:

  • Field types are mapped from Django Field to Pydantic annotations based on the dictionary below:
DJANGO_FIELD_MAP = {
    # Numerical related fields
    "AutoField": int,
    "BigAutoField": int,
    "IntegerField": int,
    "SmallIntegerField": int,
    "BigIntegerField": int,
    "PositiveIntegerField": PositiveInt,
    "PositiveSmallIntegerField": PositiveInt,
    "FloatField": float,
    "DecimalField": Decimal,
    # String related fields
    "CharField": str,
    "TextField": str,
    "SlugField": str,
    "EmailField": EmailStr,
    "URLField": AnyUrl,
    "FilePathField": FilePath,
    "FileField": FilePath,
    "ImageField": FilePath,
    # Other built-in fields
    "BooleanField": bool,
    "BinaryField": bytes,
    "DateField": date,
    "DateTimeField": datetime,
    "DurationField": timedelta,
    "TimeField": time,
    "UUIDField": UUID,
    "GenericIPAddressField": IPvAnyAddress,
    "JSONField": Json,
}
  • If Django field max_length is set, the Pydantic field will also be set with max_length equal to the Django field max_length.
  • If Django field has blank=True, the Pydantic field will have min_length=0.
  • If Django field has blank=False, the Pydantic field will have min_length=1.
  • If Django field has null=True, the Pydantic field will have field_type | None.
  • If Django field has default value set, the Pydantic field will have default set to the Django field default. In case this value is a callable, it will be used for the pydantic field default_factory.
  • If Django field has choices set, the Pydantic field will sue as a type an created Enum based on the specified choices set to the Django field. If the field is int based, the Enum will be an IntEnum. If the field is str based, the Enum will be StrEnum, otherwise it will be an Enum.

TODO

  • Add support for lower Python versions (3.6+).
  • Add support for Django model relations.
  • Add support for Django model inheritance.
  • Add support for Django model fields with custom validators.
  • Add support to customize the serializer fields.
  • Add support to serialize model properties.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pydref_serializers-0.2.4.tar.gz (8.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydref_serializers-0.2.4-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file pydref_serializers-0.2.4.tar.gz.

File metadata

  • Download URL: pydref_serializers-0.2.4.tar.gz
  • Upload date:
  • Size: 8.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.5 Linux/5.15.0-1039-aws

File hashes

Hashes for pydref_serializers-0.2.4.tar.gz
Algorithm Hash digest
SHA256 c739cc216c04820b6be3a4661cb33c9173f86d24392564026cb2abc3e0647d25
MD5 904f6e2820eefdee66f2889bc5b293c4
BLAKE2b-256 38db0428bb102d5407993c1911fcf6ba2e16f326a558f39d8b5f7535ac827064

See more details on using hashes here.

File details

Details for the file pydref_serializers-0.2.4-py3-none-any.whl.

File metadata

  • Download URL: pydref_serializers-0.2.4-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.11.5 Linux/5.15.0-1039-aws

File hashes

Hashes for pydref_serializers-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 5857803f634358324415c24dff961080175e8592faeb518495d7ab65faad6856
MD5 9592f882890b38ab0a6e7dc0903a1103
BLAKE2b-256 28b167febc5afa744c4cfa6d405651f7110d11df68979cead014e4f9ab60fc2f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page