django rest framework
TRANSCRIPT
Django REST FrameworkJenny Olsson
Load Impact
Framework for building REST applications
pip install djangorestframework
Django REST Framework (DRF)
● URL-routing● Views/ViewSets● Serializers
What do you get from DRF:
We’ll assume we’ve got:
● A Django Application● A Snail Model
Let’s build a snail API!
Request:GET www.api.snails.com/snails/1
Reply:{'id': 1,
'name': 'Helix Aspersa',
'description': 'Common garden snail'}
Example
from django.conf.urls import url, patterns, include
from rest_framework import routers
router = routers.DefaultRouter(trailing_slash=False)
# /snails
router.register(r'snails', SnailViewSet, base_name='snail')
urlpatterns = (patterns(
'',
url('', include(router.urls)),
))
URL routing
A ViewSet is a set of Views (this is a useful abstraction)
This is where you:
● Handle the request● Check permissions● Authenticate● Define allowed methods
ViewSet
from rest_framework import viewsets
from snail_app import models
from serializers import SnailSerializer
class SnailViewSet(viewsets.ModelViewSet):
queryset = models.Snail.objects.all()
serializer_class = SnailSerializer
permission_classes = (IsMember,)
/views/snails.py
This is where you:
● Validate input● Format input data● Format output data
Serializers
from rest_framework import serializers
from snail_app import models
class SnailSerializer(serializers.ModelSerializer):
class Meta:
model = models.Snail
fields = (
'id',
'name',
'description'
)
/serializers/snails.py
Request:GET www.api.snails.com/snails/1
Reply:{'id': 1,
'name': 'Helix Aspersa',
'description': 'Common garden snail'}
Example
● I want to show you some more hacky stuff, because reality
I’ll go through how to
● Create a non REST endpoint● Add a custom field to a serializer (and remove field)
DRF Website has good tutorials
Standard REST endpoints are connected to resource:
POST /snails <-- create snailGET /snails <--- list snailsGET /snails/1 <--- get snailUPDATE /snails/1 <--- update snail
But what if we want:
POST /snails/1/befriend ← befriend snail
Non REST endpoints
class SnailViewSet(viewsets.ModelViewSet):
…
@detail_route(methods=['post'])
def befriend(self, request, pk=None):
# Somehow befriend snail
return Response({'msg': 'Yay got snail friend'})
Use @detail_route or @list_route
Since we use ViewSets the endpoint will be automatically routed.
We can now befriend snails by posting to:
/snails/1/befriend
Automatic routing FTW
Our SnailSerializer is based on our model Snail.
But what if we want to return something that’s not a model field?
Adding custom fields
class SnailSerializer(serializers.ModelSerializer):
extra_snail_fact = serializers.SerializerMethodField()
class Meta:
model = models.Snail
fields = ('id', 'name', 'description', 'extra_snail_fact')
def get_extra_snail_fact(self, obj):
return 'snails really can’t swim:('
SerializerMethodField
Request:GET www.api.snails.com/snails/1
Reply:{'id': 1,
'name': 'Helix Aspersa',
'description': 'Common garden snail',
'extra_snail_fact': 'snails really can’t swim:('}
Example
But what if we DON’T want to return all the fields from our model?
class Snail(models.model):
…
super_embarrasing_hacky_field = 2
Removing fields
class SnailSerializer(serializers.ModelSerializer):
class Meta:
model = models.Snail
fields = ('id', 'name', 'description') # Just don’t add it here
SerializerMethodField
Django REST Framework is really powerful for making APIs out of Django applications.
For something more lightweight I would probably recommend flask.
Conclusion
Thanks for listening!
Ping me later if you’ve got any questions!
That’s it