# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
import json
+import os.path
+from django.conf import settings
from django.http import Http404, HttpResponse
from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache
-from rest_framework.generics import ListAPIView, RetrieveAPIView, get_object_or_404
+from rest_framework.generics import (ListAPIView, RetrieveAPIView,
+ RetrieveUpdateAPIView, get_object_or_404)
from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
from rest_framework.response import Response
from rest_framework import status
book_tag_categories = ['author', 'epoch', 'kind', 'genre']
+class CreateOnPutMixin:
+ '''
+ Creates a new model instance when PUTting a nonexistent resource.
+ '''
+ def get_object(self):
+ try:
+ return super().get_object()
+ except Http404:
+ if self.request.method == 'PUT':
+ lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
+ return self.get_queryset().model(**{
+ self.lookup_field: self.kwargs[lookup_url_kwarg]
+ })
+ else:
+ raise
+
+
class CollectionList(ListAPIView):
- queryset = Collection.objects.all()
+ queryset = Collection.objects.filter(listed=True)
serializer_class = serializers.CollectionListSerializer
@vary_on_auth # Because of 'liked'.
-class CollectionDetail(RetrieveAPIView):
+class CollectionDetail(CreateOnPutMixin, RetrieveUpdateAPIView):
+ permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
queryset = Collection.objects.all()
lookup_field = 'slug'
serializer_class = serializers.CollectionSerializer
queryset = Book.objects.none() # Required for DjangoModelPermissions
serializer_class = serializers.BookListSerializer
+ def get(self, request, filename=None, **kwargs):
+ if filename and not kwargs.get('tags') and 'count' not in request.query_params:
+ try:
+ with open(os.path.join(settings.MEDIA_ROOT, 'api', '%s.%s' % (filename, request.accepted_renderer.format)), 'rb') as f:
+ content = f.read()
+ return HttpResponse(content, content_type=request.accepted_media_type)
+ except:
+ pass
+ return super().get(request, filename=filename, **kwargs)
+
def get_queryset(self):
try:
tags, ancestors = read_tags(
name = request.POST.get('name', '')
part_name = request.POST.get('part_name', '')
+ project_description = request.POST.get('project_description', '')
+ project_icon = request.POST.get('project_icon', '')
+
_rest, slug = request.POST['book'].rstrip('/').rsplit('/', 1)
book = Book.objects.get(slug=slug)
bm.name = name
bm.part_name = part_name
bm.index = index
+ bm.project_description = project_description
+ bm.project_icon = project_icon
bm.file.save(None, request.data['file'], save=False)
bm.save(parts_count=parts_count)
class TagView(RetrieveAPIView):
+ permission_classes = [DjangoModelPermissionsOrAnonReadOnly]
serializer_class = serializers.TagDetailSerializer
-
+ queryset = Tag.objects.all()
+
def get_object(self):
- return get_object_or_404(
- Tag,
- category=self.kwargs['category'],
- slug=self.kwargs['slug']
- )
+ try:
+ return get_object_or_404(
+ Tag,
+ category=self.kwargs['category'],
+ slug=self.kwargs['slug']
+ )
+ except Http404:
+ if self.request.method == 'POST':
+ return Tag(
+ category=self.kwargs['category'],
+ slug=self.kwargs['slug']
+ )
+ else:
+ raise
+
+ def post(self, request, **kwargs):
+ data = json.loads(request.POST.get('data'))
+ fields = {
+ "name_pl": "name_pl",
+ "description_pl": "description_pl",
+ "plural": "plural",
+ "is_epoch_specific": "genre_epoch_specific",
+ "collective_noun": "collective_noun",
+ "adjective_feminine_singular": "adjective_feminine_singular",
+ "adjective_nonmasculine_plural": "adjective_nonmasculine_plural",
+ }
+ obj = self.get_object()
+ for data_field, model_field in fields.items():
+ setattr(obj, model_field, data.get(data_field, getattr(obj, model_field)))
+ if obj.pk:
+ obj.save(update_fields=fields.values(), quick=True)
+ else:
+ obj.save()
+ return Response({})
@vary_on_auth # Because of 'liked'.