The simple but powerful elegance of Django REST Framework · Django REST Framework The simple but...

Post on 15-Aug-2020

20 views 0 download

Transcript of The simple but powerful elegance of Django REST Framework · Django REST Framework The simple but...

start

Django REST Framework

The simplebut powerfulelegance of

next

Morten Barklund

Full-stackFreelancer

Rookie Pythonista Decent Djangoneer

2

Table of

Contents

01 Django RESTFramework

02 Permissions

03 Examples

04 More

next3

01

next

Django REST Framework• JSON-based REST

API

• Heavily ORM-backed serialization

• Authentication

• Validation

4

next5

from django.contrib.auth.models import Userfrom rest_framework import serializers

class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('username', 'email', )

next6

from django.contrib.auth.models import Userfrom rest_framework import viewsetsfrom .serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet): queryset = User.objects.all() serializer_class = UserSerializer

next7

from django.conf.urls import url, includefrom rest_framework import routersfrom . import views

router = routers.DefaultRouter()router.register(r'users', views.UserViewSet)

urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include(‘rest_framework.urls', namespace='rest_framework'))]

next8

INSTALLED_APPS = ( ... 'rest_framework',)

REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.AllowAny', )}

next9

GET /users/POST /users/GET /users/<pk>/PUT /users/<pk>/PATCH /users/<pk>/DELETE /users/<pk>/

02

next

Permissions

• Who can do what

• Object collections

• Individual objects

10

next11

class Book(models.Model): author = models.ForeignKey('User') title = models.TextField()

class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ('author', 'title', )

class BookViewSet(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer

router = routers.DefaultRouter()router.register(r'books', BookViewSet)

next12

INSTALLED_APPS = ( ... 'dry_rest_permissions',)

next13

from dry_rest_permissions.generics import DRYPermissions

class BookViewSet(viewsets.ModelViewSet): permission_classes = (DRYPermissions,) queryset = Book.objects.all() serializer_class = BookSerializer

next14

class Book(models.Model): author = models.ForeignKey('User') ...

@staticmethod def has_read_permission(request): return True

@staticmethod def has_write_permission(request): return False

@staticmethod @authenticated_users def has_create_permission(request): return True

next15

class Book(models.Model): ...

@staticmethod @authenticated_users def has_write_permission(request): return True

def has_object_write_permission(self, request): return request.user == self.author

next16

class Book(models.Model): ...

@allow_staff_or_superuser def has_object_delete_permission(self, request): return request.user == self.author

03

next

Examples

17

next18

class Group(models.Model): name = models.CharField(max_length=128) is_public = models.BooleanField(default=True) members = models.ManyToManyField(“User", through='Membership')

class Membership(models.Model): user = models.ForeignKey("User") group = models.ForeignKey(Group) is_admin = models.BooleanField(default=False)

next19

class GroupSerializer(serializers.ModelSerializer): class Meta: model = 'group' fields = ('name', 'members', )

class GroupViewSet(viewsets.ModelViewSet): permission_classes = (DRYPermissions,) queryset = Group.objects.all() serializer_class = GroupSerializer

router = routers.DefaultRouter()router.register(r'groups', GroupViewSet)

next20

class Group(models.Model): ...

@authenticated_users def has_object_read_permission(self, request): return self.is_public or self.members.filter(pk=request.user.pk).exists()

next21

class Group(models.Model): ...

@authenticated_users def has_object_read_permission(self, request): return self.is_public or self.members.filter(pk=request.user.pk).exists()

def has_object_write_permission(self, request): return self.membership_set \ .get(user=request.user).is_admin

next22

class Message(models.Model): group = models.ForeignKey(Group) author = models.ForeignKey("User") body = models.TextField()

next23

class Message(models.Model): group = models.ForeignKey(Group) author = models.ForeignKey("User") body = models.TextField()

def has_object_read_permission(self, request): return self.group.has_object_read_permission(request)

next24

class Message(models.Model): group = models.ForeignKey(Group) author = models.ForeignKey("User") body = models.TextField()

def has_object_read_permission(self, request): return self.group.has_object_read_permission(request)

def has_object_write_permission(self, request): return self.author == request.user

next25

class Message(models.Model): group = models.ForeignKey(Group) author = models.ForeignKey("User") body = models.TextField()

def has_object_read_permission(self, request): return self.group.has_object_read_permission(request)

def has_object_write_permission(self, request): return self.author == request.user

def has_object_delete_permission(self, request): return self.author == request.user or self.group.has_object_write_permission(request)

next26

class Comment(models.Model): message = models.ForeignKey(Message) commenter = models.ForeignKey("User") reply = models.TextField()

next27

class Comment(models.Model): message = models.ForeignKey(Message) commenter = models.ForeignKey("User") reply = models.TextField()

def has_object_read_permission(self, request): return self.message \ .has_object_read_permission(request)

next28

class Comment(models.Model): message = models.ForeignKey(Message) commenter = models.ForeignKey("User") reply = models.TextField()

def has_object_read_permission(self, request): return self.message \ .has_object_read_permission(request)

def has_object_write_permission(self, request): return self.commenter == request.user

next29

class Comment(models.Model): message = models.ForeignKey(Message) commenter = models.ForeignKey("User") reply = models.TextField()

def has_object_read_permission(self, request): return self.message \ .has_object_read_permission(request)

def has_object_write_permission(self, request): return self.commenter == request.user

def has_object_delete_permission(self, request): return self.commenter == request.user or self.message.has_object_delete_permission(request)

04

next

More

30

• Read the docs

close

Thank You

Presenter: Morten Barklund@barklund?