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 withmax_length
equal to the Django fieldmax_length
. - If Django field has
blank=True
, the Pydantic field will havemin_length=0
. - If Django field has
blank=False
, the Pydantic field will havemin_length=1
. - If Django field has
null=True
, the Pydantic field will havefield_type | None
. - If Django field has
default
value set, the Pydantic field will havedefault
set to the Django fielddefault
. In case this value is a callable, it will be used for the pydantic fielddefault_factory
. - If Django field has
choices
set, the Pydantic field will sue as a type an created Enum based on the specifiedchoices
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
Built Distribution
Hashes for pydref_serializers-0.2.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5857803f634358324415c24dff961080175e8592faeb518495d7ab65faad6856 |
|
MD5 | 9592f882890b38ab0a6e7dc0903a1103 |
|
BLAKE2b-256 | 28b167febc5afa744c4cfa6d405651f7110d11df68979cead014e4f9ab60fc2f |