5 - Relationships and hyperlinked APIs - Django REST framework (django-rest-framework.org)
Django REST Framework
Relationships & Hyperlinked APIs
Creating an endpoint for the root of our API
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from rest_framework import generics, permissions
from django.contrib.auth.models import User
from snippets.permissions import IsOwnerOrReadOnly
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
serializer_class = SnippetSerializer
class UserList(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'users':reverse('user-list', request=request, format=format),
'snippets':reverse('snippet-list', request=request, format=format)
})
- Response : 정규화된 URL을 반환하는 rest framework 함수
Creating an endpoint for the highlighted snippets
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer, UserSerializer
from rest_framework import generics, permissions, renderers
from django.contrib.auth.models import User
from snippets.permissions import IsOwnerOrReadOnly
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Snippet.objects.all()
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
serializer_class = SnippetSerializer
class UserList(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
@api_view(['GET'])
def api_root(request, format=None):
return Response({
'users':reverse('user-list', request=request, format=format),
'snippets':reverse('snippet-list', request=request, format=format)
})
class SnippetHighlight(generics.GenericAPIView):
queryset = Snippet.objects.all()
renderer_classes = [renderers.StaticHTMLRenderer]
def get(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
Hyperlinking our API
- 엔티티 간의 관계를 표현하는 방식
- primary key 사용하기
- 하이퍼링크 사용하기
- 등등
from rest_framework import serializers
from django.contrib.auth.models import User
from snippets.models import Snippet, LANGUAGE_CHOICES,STYLE_CHOICES
class SnippetSerializer(serializers.Serializer):
owner = serializers.ReadOnlyField(source='owner.username')
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(required=False, allow_blank=True, max_length=100)
code = serializers.CharField(style={'base_template':'textarea.html'})
linenos = serializers.BooleanField(required=False)
language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')
def create(self, validated_data):
return Snippet.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.code = validated_data.get('code', instance.code)
instance.linenos = validated_data.get('linenos', instance.linenos)
instance.language = validated_data.get('language', instance.language)
instance.style = validated_data.get('style', instance.style)
instance.save()
return instance
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight',format='html')
class Meta:
model = Snippet
fields = ['url', 'id', 'highlight', 'owner',
'title', 'code', 'linenos', 'language', 'style']
class UserSerializer(serializers.HyperlinkedModelSerializer):
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)
class Meta:
model = User
fields = ['url', 'id', 'username', 'snippets']
Making sure our URL patterns are named
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
#API endpoints
urlpatterns = format_suffix_patterns([
path('', views.api_root),
path('snippets/',
views.SnippetList.as_view(),
name='snippet-list'),
path('snippets/<int:pk>/',
views.SnippetDetail.as_view(),
name='snippet-detail'),
path('snippets/<int:pk>/highlight/',
views.SnippetHighlight.as_view(),
name='snippet-highlight'),
path('users/',
views.UserList.as_view(),
name='user-list'),
path('users/<int:pk>/',
views.UserDetail.as_view(),
name='user-detail')
])
Adding pagination
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE':10
}
'Computer Science > BackEnd' 카테고리의 다른 글
Django API #3 | Serializing and Deserializing Data (0) | 2022.09.11 |
---|---|
장고 DRF #6 | Django REST framework ViewSets & Routers (0) | 2022.09.11 |
장고 DRF #3 | Django REST framework Class-based Views (0) | 2022.09.09 |
장고 DRF #2 | Django REST framework Requests and Responses (0) | 2022.09.09 |
장고 DRF #1 | Django REST framework Serialization (0) | 2022.09.09 |