Django Rest Framework
Overview:
http request --> url_route --> view --> serializer --> data-dict response
Flows
--> http request
url_route (urls.py)
view (views.py) # adds context for serializer
serializer (serializers.py)
db (models.py)
<-- data-dict response
Create: post data-dict --(deserialize)--> Object
Update: patch id, data-dict --> new data
Delete: delete id -->
Get: get id --(serialize)--> data-dict
List: get --> list of data-dicts
# Object -> dict
s = Serializer(obj)
s.data
Move from the raw form to python native dict.
# dict -> Object
s = Serializer(data={..})
s.is_valid()
s.validated_data
Construct the Object from the python native parts and validate the parts (inputs) meet any requirements or format.
s = Serializer(data={..})
if s.is_valid():
s.validated_data
else:
s.errors # dict(field=[problems..])
class SimpleView(APIView):
def post(self, request, *args, **kws):
request.data
return Response(..)
def get(self, request, *args, **kws):
request.query_params
...
def patch(self, request, *args, **kws):
...
def delete(self, request, *args, **kws):
...
class SimpleViewSet(ViewSet): # ModelViewSet
serializer_class = SimpleSerializer
def create(self, request, *args, **kws):
return Response(..)
def update(self, request, *args, **kws):
def partial_update(self, request, *args, **kws):
def destroy(self, request, *args, **kws):
def retrieve(self, request, *args, **kws):
def list(self, request, *args, **kws):
More features.
class SimpleViewSet(ViewSet): # ModelViewSet
serializer_class = SimpleSerializer
lookup_field = 'field'
authentication_classes = ()
permissions_classes = ()
def create(self, request, *args, **kws):
...
def get_queryset(self):
...
Model or class file
# simple.py
from datetime import datetime
class Simple:
def __init__(self, name, email, created_at=None):
self.name = name
self.email = email
self.created_at = created_at or datetime.utcnow()
def save(self):
# persist
Serializers file
# serializers.py
from rest_framework import serializers
class SimpleSerializer(serializers.Serializer):
name = serializers.CharField(max_length=128)
email = serializers.EmailField()
created_at = serializers.DateTimeField()
# serialize
obj = Simple('Charles', '[email protected]')
serializer = SimpleSerializer(obj) # obj becomes serializer.instance
print(serializer.data) # -> data-dict {'name': 'Charles', 'email': '[email protected]', 'created_at': '2018-07-16T19:45:39.583565Z'}
from rest_framework.renderers import JSONRenderer
json = JSONRenderer().render(serializer.data) # -> str
# deserialize
from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser
stream = BytesIO(json)
data = JSONParser().parse(stream)
serializer = SimpleSerializer(data=data) # data becomes available as serializer.initial_data
serializer.is_valid() # -> bool
if is_valid: # always check before using validated data
serializer.validated_data # -> data-dict {'name': 'Charles', 'email': '[email protected]', 'created_at': '2018-07-16T19:45:39.583565Z'}
else:
serializer.errors # explains what went wrong
#
# save() # -> object: puts the data-dict to it's destination (db, email, class obj)
# -> create(validated_data) # -> object: Model.objects.create()
# -> update(orig_object_instance, validated_data) # -> object: model_object.foo = vdata['bar']; model_object.save()
Args
- read_only (False) in output, not allowed input,
- write_only (False) in create and update, not in output
- required (True) raise if not supplied for serialization
- allow_null (False) None is considered a valid value