file_picture.py 3.02 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
from django.db import models
from rest_framework import serializers
from rest_framework.response import Response

from backend_app.models.abstract.base import (
    BaseModel,
    BaseModelSerializer,
    BaseModelViewSet,
)
from backend_app.permissions.app_permissions import NoDelete, IsStaff, IsOwner, ReadOnly
from backend_app.validation.validators import ImageValidator
from base_app.models import User


#########
# Models
#########


class AbstractFile(BaseModel):
    owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    file = models.FileField(upload_to="files/%Y/%m/%d/", blank=True, null=True)
    title = models.CharField(max_length=200, default="", blank=True, null=True)
    licence = models.CharField(max_length=100, default="", blank=True, null=True)
    description = models.CharField(max_length=500, default="", blank=True, null=True)

    class Meta:
        abstract = True


class File(AbstractFile):
    pass


class Picture(AbstractFile):
    file = models.FileField(
        upload_to="pictures/%Y/%m/%d/",
        blank=True,
        null=True,
        validators=[ImageValidator()],
    )


#########
# Serializers
#########


class FileSerializer(BaseModelSerializer):
    owner = serializers.StringRelatedField(read_only=True)

    def save(self, *args, **kwargs):
        instance = super().save(*args, **kwargs)
        instance.owner = self.get_user_from_request()
        instance.save()
        return instance

    class Meta:
        model = File
        fields = BaseModelSerializer.Meta.fields + (
            "owner",
            "file",
            "title",
            "licence",
            "description",
        )


class PictureSerializer(FileSerializer):
    class Meta:
        model = Picture
        fields = FileSerializer.Meta.fields


class FileSerializerFileReadOnly(FileSerializer):
    file = serializers.FileField(read_only=True)


class PictureSerializerFileReadOnly(PictureSerializer):
    file = serializers.FileField(read_only=True)


#########
# ViewSets
#########


class BaseFileViewSet(BaseModelViewSet):
    _serializer_not_read_only = None
    _serializer_read_only = None

    def get_serializer_class(self):
        """
        Custom get serializer to make file field readonly after it has been created
        """
        if hasattr(self, "request") and self.request.method == "PUT":
            return self._serializer_read_only
        else:
            return self._serializer_not_read_only

    def list(self, request, *args, **kwargs):
        # Prevent the querying of all objects.
        return Response(list())

    permission_classes = (NoDelete | IsStaff, IsOwner | IsStaff | ReadOnly)


class FileViewSet(BaseModelViewSet):
    _serializer_not_read_only = PictureSerializer
    _serializer_read_only = PictureSerializer
    queryset = File.objects.all()
    end_point_route = "files"


class PictureViewSet(BaseFileViewSet):
    _serializer_not_read_only = PictureSerializer
    _serializer_read_only = PictureSerializer
    queryset = Picture.objects.all()
    end_point_route = "pictures"