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"