from api.utils import never_cache
+from django.db.models import Q
from django.http import Http404, JsonResponse
from django.shortcuts import render, get_object_or_404
from django.views.decorators import cache
import re
from rest_framework.generics import ListAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView
from rest_framework import serializers
-from rest_framework.permissions import IsAuthenticated
+from rest_framework.permissions import SAFE_METHODS, IsAuthenticated, IsAuthenticatedOrReadOnly
from api.fields import AbsoluteURLField
+from catalogue.api.serializers import BookSerializer2
+
+
+class BookmarkSerializerV3(serializers.ModelSerializer):
+ """Replaced in API v4."""
+ book = serializers.SlugRelatedField(
+ queryset=catalogue.models.Book.objects.all(), slug_field='slug',
+ required=False
+ )
+ href = AbsoluteURLField(view_name='api_bookmark', view_args=['uuid'])
+ timestamp = serializers.IntegerField(required=False)
+ location = serializers.CharField(required=False)
+
+ class Meta:
+ model = models.Bookmark
+ fields = ['book', 'anchor', 'audio_timestamp', 'mode', 'note', 'href', 'uuid', 'location', 'timestamp', 'deleted']
+ read_only_fields = ['uuid', 'mode']
class BookmarkSerializer(serializers.ModelSerializer):
- book = serializers.SlugRelatedField(queryset=catalogue.models.Book.objects.all(), slug_field='slug')
+ book_slug = serializers.SlugRelatedField(
+ queryset=catalogue.models.Book.objects.all(), slug_field='slug',
+ write_only=True,
+ required=False
+ )
+ book = BookSerializer2(read_only=True)
href = AbsoluteURLField(view_name='api_bookmark', view_args=['uuid'])
+ timestamp = serializers.IntegerField(required=False)
+ location = serializers.CharField(required=False)
class Meta:
model = models.Bookmark
- fields = ['book', 'anchor', 'note', 'href']
+ fields = ['book_slug', 'book', 'anchor', 'audio_timestamp', 'mode', 'note', 'href', 'uuid', 'location', 'timestamp', 'deleted']
+ read_only_fields = ['uuid', 'mode']
+ def create(self, validated_data):
+ book = validated_data.pop('book_slug', None)
+ if book is not None:
+ validated_data['book'] = book
+ return super().create(validated_data)
+ def update(self, instance, validated_data):
+ book = validated_data.pop('book_slug', None)
+ if book is not None:
+ validated_data['book'] = book
+ return super().update(instance, validated_data)
@never_cache
class BookmarksView(ListCreateAPIView):
permission_classes = [IsAuthenticated]
- serializer_class = BookmarkSerializer
+ def get_serializer_class(self):
+ if self.request.version < 'v4':
+ return BookmarkSerializerV3
+ else:
+ return BookmarkSerializer
+
def get_queryset(self):
return self.request.user.bookmark_set.all()
@never_cache
class BookBookmarksView(ListAPIView):
permission_classes = [IsAuthenticated]
- serializer_class = BookmarkSerializer
pagination_class = None
+ def get_serializer_class(self):
+ if self.request.version < 'v4':
+ return BookmarkSerializerV3
+ else:
+ return BookmarkSerializer
+
def get_queryset(self):
return self.request.user.bookmark_set.filter(book__slug=self.kwargs['book'])
@never_cache
class BookmarkView(RetrieveUpdateDestroyAPIView):
- permission_classes = [IsAuthenticated]
- serializer_class = BookmarkSerializer
+ permission_classes = [IsAuthenticatedOrReadOnly]
lookup_field = 'uuid'
+ def get_serializer_class(self):
+ if self.request.version < 'v4':
+ return BookmarkSerializerV3
+ else:
+ return BookmarkSerializer
+
def get_queryset(self):
- return self.request.user.bookmark_set.all()
+ if self.request.method in SAFE_METHODS:
+ q = Q(deleted=False)
+ if self.request.user.is_authenticated:
+ q |= Q(user=self.request.user)
+ return models.Bookmark.objects.filter(q)
+ else:
+ return self.request.user.bookmark_set.all()