An alternative serializer implementation for REST framework written in cython built for speed.
Project description
drf-turbo
Overview
drf-turbo is a drop-in serializer for Django REST Framework (DRF). drf-turbo serializers run around 7.75 times faster than what what you get from DRF’s packaged serializer.
Requirements
Django
Django REST Framework
pytz
forbiddenfruit
pyyaml(OpenAPI)
uritemplate(OpenAPI)
djangorestframework-simplejwt(OpenAPI)
Installation
$ pip install drf-turbo
To install Cython on MacOS via Brew:
$ brew install cython
Performance
drf-turbo serialization, deserialization and validation performance averages 86% faster than DRF’s standard serializer.
For more details, visit the benchmarks section of the docs.
Documentation & Support
Documentation for the project is available at https://drf-turbo.readthedocs.io.
For questions and support, use github issues
Examples
Declaring Serializers
from datetime import datetime
from django.utils.timezone import now
import drf_turbo as dt
class User:
def __init__(self, username, email,created=None):
self.username = username
self.email = email
self.created = created or datetime.now()
user = User(username='test' , email='test@example.com')
class UserSerializer(dt.Serializer):
username = dt.StrField(max_length=50)
email = dt.EmailField()
created = dt.DateTimeField()
Serializing objects
serializer = UserSerializer(user)
serializer.data
# {'username': 'test', 'email': 'test@example.com', 'created': '2021-11-04T22:49:01.981127Z'}
Deserializing objects
data = {'username':'new_test','email':'test2@example.com','created':now()}
serializer = UserSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# {'username': 'new_test', 'email': 'test2@example.com', 'created': datetime.datetime(2021, 11, 12, 6, 10, 44, 85118)}}
Validation
serializer = UserSerializer(data={'email': 'test'})
serializer.is_valid()
# False
serializer.errors
# {'username': ['This field is required.'], 'email': ['Enter a valid email address.'],'created': ['This field is required.']}
Field-level validation
import drf_turbo as dt
class UserSerializer(dt.Serializer):
username = dt.StrField(max_length=50)
def validate_username(self, value):
if 'test' not in value.lower():
raise dt.ValidationError("test must be in username")
return value
Object-level validation
import drf_turbo as dt
class CampaignSerializer(dt.Serializer):
start_date = dt.DateTimeField()
end_date = dt.DateTimeField()
def validate(self, data):
if data['start_date'] > data['end_date']:
raise dt.ValidationError("start_date must occur before end_date")
return data
Nested Serializers
from datetime import datetime
from django.utils.timezone import now
import drf_turbo as dt
class User:
def __init__(self, username, email,created=None):
self.username = username
self.email = email
self.created = created or datetime.now()
user = User(username='test' , email='test@example.com')
class UserSerializer(dt.Serializer):
username = dt.StrField(max_length=50)
email = dt.EmailField()
created = dt.DateTimeField()
class Profile :
def __init__(self, age=25):
self.age = age
self.user = user
profile = Profile()
class ProfileSerializer(dt.Serializer):
age = dt.IntField()
user = UserSerializer()
serializer = ProfileSerializer(profile)
serializer.data
# {'age' : 25 , 'user' : {'username': 'test', 'email': 'test@example.com', 'created': '2021-11-04T22:49:01.981127Z'}}
Filtering Output
drf-turbo provides option to enclude or exclude fields from serializer using only or exclude keywords.
serializer = UserSerializer(user,only=('id','username'))
or
serializer = ProfileSerializer(profile,exclude=('id','user__email'))
or
http://127.0.0.1:8000/user/?only=id,username
Required Fields
Make a field required by passing required=True. An error will be raised if the the value is missing from data during Deserializing.
For example:
class UserSerializer(dt.Serializer):
username = dt.StrField(required=True,error_messages={"required":"no username"})
Specifying Defaults
It will be used for the field if no input value is supplied.
For example:
from datetime import datetime
class UserSerializer(dt.Serializer):
birthdate = dt.DateTimeField(default=datetime(2021, 11, 05))
ModelSerializer
Mapping serializer to Django model definitions.
Features :
It will automatically generate a set of fields for you, based on the model.
It will automatically generate validators for the serializer.
It includes simple default implementations of .create() and .update().
class UserSerializer(dt.ModelSerializer):
class Meta :
model = User
fields = ('id','username','email')
You can also set the fields attribute to the special value __all__ to indicate that all fields in the model should be used.
For example:
class UserSerializer(dt.ModelSerializer):
class Meta :
model = User
fields = '__all__'
You can set the exclude attribute to a list of fields to be excluded from the serializer.
For example:
class UserSerializer(dt.ModelSerializer):
class Meta :
model = User
exclude = ('email',)
Read&Write only fields
class UserSerializer(dt.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'password','password_confirmation')
read_only_fields = ('username')
write_only_fields = ('password','password_confirmation')
OpenApi(Swagger)
Add drf-turbo to installed apps in settings.py
INSTALLED_APPS = [
# ALL YOUR APPS
'drf_turbo',
]
and then register our openapi AutoSchema with DRF.
REST_FRAMEWORK = {
# YOUR SETTINGS
'DEFAULT_SCHEMA_CLASS': 'drf_turbo.openapi.AutoSchema',
}
and finally add these lines in urls.py
from django.views.generic import TemplateView
from rest_framework.schemas import get_schema_view as schema_view
from drf_turbo.openapi import SchemaGenerator
urlpatterns = [
# YOUR PATTERNS
path('openapi', schema_view(
title="Your Project",
description="API for all things …",
version="1.0.0",
generator_class=SchemaGenerator,
public=True,
), name='openapi-schema'),
path('docs/', TemplateView.as_view(
template_name='docs.html',
extra_context={'schema_url':'openapi-schema'}
), name='swagger-ui'),
]
Now go to http://127.0.0.1:8000/docs
Credits
This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.
License
Free software: MIT license
History
0.1.0 (2021-11-10)
First release on PyPI.
0.1.2 (2021-11-11)
performance improvments
0.1.3 (2021-11-12)
fix override error messages
0.1.5 (2021-11-21)
fix get_attribute on related field issue
0.1.6 (2022-05-29)
clean project
drop support for renderers,parsers, and responses
remove deprecated methods
0.1.7 (2023-08-19)
pin requirements
use c extensions
0.1.8 (2023-10-11)
add support for django 4.0
0.1.9 (2023-10-11)
add support for python 3.10
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file drf-turbo-0.1.9.tar.gz
.
File metadata
- Download URL: drf-turbo-0.1.9.tar.gz
- Upload date:
- Size: 565.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.18
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6155879be62064894e744c3ba614a7fd65ef78a12a357595ffaa9ce952422251 |
|
MD5 | 26bf69b0b13fd190d61529dd881f7c42 |
|
BLAKE2b-256 | 2157957549fdd3d58babf6ce9d4f6c035d7ce15af38015fd52549cf5dfaf5626 |