Skip to content

Commit aa409c8

Browse files
committed
Add endpoint for highligted snippets, use HyperlinkedModelSerializer instead of ModelSerializer
1 parent 2f288ab commit aa409c8

File tree

8 files changed

+41
-13
lines changed

8 files changed

+41
-13
lines changed

tutorial4/db.sqlite3

0 Bytes
Binary file not shown.

tutorial5/db.sqlite3

48 KB
Binary file not shown.
Binary file not shown.
189 Bytes
Binary file not shown.
891 Bytes
Binary file not shown.

tutorial5/snippets/serializers.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,25 @@
2828
# instance.style = validated_data.get('style', instance.style)
2929
# instance.save()
3030
# return instance
31+
3132

32-
33-
class SnippetSerializer(serializers.ModelSerializer):
34-
# why do we need to explicitly specify here whilde Snippet model alreayd has this field?
33+
class SnippetSerializer(serializers.HyperlinkedModelSerializer):
34+
# why do we need to explicitly specify the owner filed here while Snippet model already has this field?
35+
# Because the owner field stored in the snippet model is a FK, which is an ID. But we need the username of the owner.
3536
owner = serializers.ReadOnlyField(source='owner.username')
3637

38+
# The highlight field in the snippet model is the entire HTML content, but here we just need its url.
39+
highlight = serializers.HyperlinkedIdentityField(view_name='snippet-highlight', format='html')
40+
3741
class Meta:
3842
model = Snippet
39-
fields = ['id', 'owner', 'title', 'code', 'linenos', 'language', 'style']
43+
fields = ['url', 'id', 'owner', 'highlight', 'title', 'code', 'linenos', 'language', 'style']
4044

4145

42-
class UserSerializer(serializers.ModelSerializer):
46+
class UserSerializer(serializers.HyperlinkedModelSerializer):
4347
# 对于 model 中不存在的 field,需要额外指定
44-
snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
48+
#snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
49+
snippets = serializers.HyperlinkedRelatedField(many=True, view_name='snippet-detail', read_only=True)
4550

4651
class Meta:
4752
model = User

tutorial5/snippets/urls.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
from snippets.serializers import UserSerializer
55

66
urlpatterns = [
7-
path('snippets/', views.SnippetList.as_view()), # When we use class-based view, we need to call as_view() to get the view form class
8-
path('snippets/<int:pk>/', views.SnippetDetail.as_view()),
9-
path('users/', views.UserList.as_view()),
10-
path('users/<int:pk>/', views.UserDetail.as_view()),
7+
path('', views.api_root),
8+
path('snippets/', views.SnippetList.as_view(), name='snippet-list'), # When we use class-based view, we need to call as_view() to get the view form class
9+
path('snippets/<int:pk>/', views.SnippetDetail.as_view(), name='snippet-detail'),
10+
path('snippets/<int:pk>/highlight/', views.SnippetHighlight.as_view(), name='snippet-highlight'),
11+
path('users/', views.UserList.as_view(), name='user-list'),
12+
path('users/<int:pk>/', views.UserDetail.as_view(), name='user-detail'),
1113
]
1214

1315

tutorial5/snippets/views.py

+24-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
from django.contrib.auth.models import User
22
from snippets.models import Snippet
33
from snippets.serializers import SnippetSerializer, UserSerializer
4-
from rest_framework import generics, permissions
4+
from rest_framework import generics, permissions, renderers
5+
from rest_framework.decorators import api_view
6+
from rest_framework.response import Response
7+
from rest_framework.reverse import reverse
58
from .permissions import IsOwnerOrReadOnly
69

710

11+
@api_view(['GET'])
12+
def api_root(request, format=None):
13+
return Response({
14+
'users': reverse('user-list', request=request, format=format),
15+
'snippets': reverse('snippet-list', request=request, format=format)
16+
})
17+
818
class SnippetList(generics.ListCreateAPIView):
919
queryset = Snippet.objects.all()
1020
serializer_class = SnippetSerializer
@@ -19,13 +29,24 @@ def perform_create(self, serializer):
1929
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
2030
queryset = Snippet.objects.all()
2131
serializer_class = SnippetSerializer
22-
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
23-
32+
permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly] # IsOwnerOrReadOnly: custom object-level permission
2433

34+
35+
class SnippetHighlight(generics.GenericAPIView):
36+
queryset = Snippet.objects.all()
37+
renderer_classes = [renderers.StaticHTMLRenderer]
38+
39+
def get(self, request, *args, **kwargs):
40+
snippet = self.get_object()
41+
return Response(snippet.highlighted)
42+
43+
2544
class UserList(generics.ListAPIView):
2645
queryset = User.objects.all()
2746
serializer_class = UserSerializer
47+
permission_classes = [permissions.IsAdminUser]
2848

2949
class UserDetail(generics.RetrieveAPIView):
3050
queryset = User.objects.all()
3151
serializer_class = UserSerializer
52+
permission_classes = [permissions.IsAdminUser]

0 commit comments

Comments
 (0)