gpt4 book ai didi

django - 在 Django REST 框架中实现 HATEOAS

转载 作者:行者123 更新时间:2023-12-02 09:03:23 25 4
gpt4 key购买 nike

我正在尝试实现使用 Django REST Framework (DRF) 实现 HATEOAS 的 REST API。我知道 DRF 本身不支持 HATEOAS,并且我没有找到任何此类实现的示例。因此,我不确定应该在哪个级别的 DRF(序列化器/ View /渲染器)上实现此功能。你有一些经验、想法、见解或例子可以帮助我开始吗?谢谢。

最佳答案

这是我在 View 集级别实现的解决方案:

from rest_framework import viewsets
from rest_framework import generics
from serializers import EventSerializer, BandSerializer
from rest_framework.response import Response
from rest_framework import status

from collections import OrderedDict

class LinksAwarePageNumberPagination(PageNumberPagination):
def get_paginated_response(self, data, links=[]):
return Response(OrderedDict([
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data),
('_links', links),
]))

class HateoasModelViewSet(viewsets.ModelViewSet):
"""
This class should be inherited by viewsets that wants to provide hateoas links
You should override following methodes:
- get_list_links
- get_retrieve_links
- get_create_links
- get_update_links
- get_destroy_links
"""

pagination_class = LinksAwarePageNumberPagination


def get_list_links(self, request):
return {}

def get_retrieve_links(self, request, instance):
return {}

def get_create_links(self, request):
return {}

def get_update_links(self, request, instance):
return {}

def get_destroy_links(self, request, instance):
return {}

def get_paginated_response(self, data, links=None):
assert self.paginator is not None
return self.paginator.get_paginated_response(data, links)

def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data, links=self.get_list_links())

serializer = self.get_serializer(queryset, many=True)

return Response(OrderedDict([
('results', serializer.data),
('_links', self.get_list_links(request))
]))

def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
data = serializer.data
data['_links'] = self.get_retrieve_links(request, instance)
return Response(data)

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
data = serializer.data
data['_links'] = self.get_create_links(request)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
data = serializer.data
data['_links'] = self.get_update_links(request, instance)
return Response(serializer.data)

def destroy(self, request, *args, **kwargs):
instance = self.get_object()
data = {'_links': self.get_destroy_links(request, instance)}
self.perform_destroy(instance)
return Response(data, status=status.HTTP_204_NO_CONTENT)

使用示例:

class EventViewSet(HateoasModelViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer

def get_list_links(self, request):
return {
'self': {'href': request.build_absolute_uri(request.path)},
'related_link1': {'href': '...'},
}

关于django - 在 Django REST 框架中实现 HATEOAS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33943995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com