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
Metadata
Release files for drf-turbo 0.1.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| drf-turbo-0.1.9.tar.gz | 565.9 kB | Without provenance | Details for drf-turbo-0.1.9.tar.gz |
Release files / drf-turbo-0.1.9.tar.gz
| Download URL | drf-turbo-0.1.9.tar.gz |
|---|---|
| Size | 565.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6155879be62064894e744c3ba614a7fd65ef78a12a357595ffaa9ce952422251
|
|
BLAKE2b-256 checksum How to use checksums |
2157957549fdd3d58babf6ce9d4f6c035d7ce15af38015fd52549cf5dfaf5626
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.8.18
|
Security for drf-turbo 0.1.9
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.