5 - Relationships and hyperlinked APIs - Django REST framework
At the moment relationships within our API are represented by using primary keys. In this part of the tutorial we'll improve the cohesion and discoverability of our API, by instead using hyperlinking for relationships. Right now we have endpoints for 'snip
www.django-rest-framework.org
# users와 snippets를 한번에 볼 수 있는 view 만들기
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
@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로 reverse라는걸 사용하는데 일단 뭔지 모르겠다. 찾아보도록 하자.
## DRF의 reverse
일단 Django의 reverse와 DRF의 reverse는 다르다고 한다.




사실 잘 모르겠다. 저렇게 적으면 해당 뷰와 연결시켜주는 기능을 하는걸까..? 다른 분들이 한국어로 튜토리얼을 정리한것은 url name을 매칭해준다고 한다. 일단 천천히 따라가보도록 하자. 그리고 만들어준 뷰를 snippets/urls.py에 등록해준다.
path('',views.api_root),
여기까지 봐서는 기본 루트 페이지를 만드는 작업 같다.
# Highlight Snippent의 EndPoint만들기
from rest_framework import renderers
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)
당연히 urls.py에 추가해준다.
path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view()),
# 하이퍼링크로 API연결하기
- primary key 사용
- entity간에 하이퍼링크로 연결
- unique identifying slug field 사용
- 관계 entity의 default string representation 사용
- 부모로 관계 entity 감싸기
- custom 하기
이 튜토리얼에서는 2번째 방법을 사용한다고 한다. 그래서 ModelSerializer -> HuperlinkedModelSerializer로 바꾸는 과정을 거쳐야 한다.
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']
ModelSerializer <-> HuperlinkedModelSerializer 의 차이점이 존재한다.
- id를 기본 필드로 사용하지 않기때문에 별도로 추가해줘야함.
- url필드를 기본적으로 사용한다.
- 관계를 위해 PrimaryKeyRelatedField 가 아닌 HyperlinkedRelatedField 사용한다.
# snippets/urls.py 수정
from django.urls import path
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')
])
다음과 같이 수정해준다.
# tutorial/settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
을 수정해주어 목록보기에 대한 크기를 지정해줄 수 도 있다.
사실 튜토리얼을 따라가는데, 내가 원하는 지향점과 점점 멀어지고 있는거 같아서 의미없는 튜토리얼이 되가는거 같다. 일단 하나 남았으니까 마지막까지 맞추도록 하겠다.