myModelSerializer.py 5.25 KB
Newer Older
1
2
from rest_framework import serializers
from django.utils import timezone
3
from .pendingModeration import PendingModeration
4
5
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
6
from backend.utils import is_member
Florent Chehab's avatar
Florent Chehab committed
7
from .myModel import MyModel
Florent Chehab's avatar
Florent Chehab committed
8
from .pendingModeration import PendingModerationSerializer
9
10
11
12
13
14
15


class MyModelSerializer(serializers.ModelSerializer):
    moderated_on = serializers.DateTimeField(
        format="%Y-%m-%d %H:%M:%S", read_only=True)
    updated_on = serializers.DateTimeField(
        format="%Y-%m-%d %H:%M:%S", read_only=True)
16
17
    moderated_by = serializers.CharField(read_only=True)
    updated_by = serializers.CharField(read_only=True)
18
19
    pending_moderation = serializers.SerializerMethodField()
    # pending_moderation = PendingModerationSerializer(many=True, read_only=True)
20

Florent Chehab's avatar
Florent Chehab committed
21
    # TODO : updated_by_username useless ? See in rest API
22
23
24
25
26
27
28
29
    updated_by_username = serializers.SerializerMethodField(read_only=True)

    def get_updated_by_username(self, obj):
        if obj.updated_by:
            return obj.updated_by.username
        else:
            return None

30
31
32
33
34
35
    def get_pending_moderation(self, obj):
        if self.context['view'].action != 'list':
            print(self.context['view'].action)
            return PendingModerationSerializer(obj.pending_moderation, many=True, read_only=True, context=self.context).data
        return None

36
37
38
39
    class Meta:
        model = MyModel

    def moderation_required(self):
Florent Chehab's avatar
Florent Chehab committed
40
41
42
        if hasattr(self.Meta, 'NEVER_MODERATE') and self.Meta.NEVER_MODERATE:
            return False

43
        user = self.get_user_in_request()
44
45
46
47
48
49
50
        request = self.context['request']

        if user.is_staff:
            return False

        if settings.MODERATION_ACTIVATED:
            if request.method in ['POST', 'PUT']:  # should be always the case
51
                return not is_member('Moderators', request.user)
52
53
54

        return False

55
56
57
    def get_user_in_request(self):
        return self.context['request'].user

58
    def set_model_attr_no_moder(self, moderated_and_updated):
59
        user = self.get_user_in_request()
60
        now = timezone.now()
Florent Chehab's avatar
Florent Chehab committed
61
62
63
64
        self.override_validated_data({
            'moderated_by': user,
            'moderated_on': now,
        })
65
66

        if moderated_and_updated:
Florent Chehab's avatar
Florent Chehab committed
67
68
69
70
            self.override_validated_data({
                'updated_by': user,
                'updated_on': now,
            })
71
72

    def clean_validated_data(self):
Florent Chehab's avatar
Florent Chehab committed
73
74
75
76
77
78
        self.override_validated_data({
            'moderated_by': None,
            'moderated_on': None,
            'updated_by': None,
            'updated_on': None,
        })
79

80
81
82
83
84
    def get_pending_models(self):
        ct = ContentType.objects.get_for_model(self.Meta.model)
        return PendingModeration.objects.filter(
            content_type=ct, object_id=self.instance.pk)

Florent Chehab's avatar
Florent Chehab committed
85
86
87
88
89
90
91
92
93
94
    def override_validated_data(self, new_data):
        """
        Method used to force specific attributes when saving a model
        """
        for key in new_data:
            self.validated_data[key] = new_data[key]

    def my_pre_save(self):
        pass

Florent Chehab's avatar
Florent Chehab committed
95
96
    def save(self, *args, **kwargs):
        return self.my_save(*args, **kwargs)
97

Florent Chehab's avatar
Florent Chehab committed
98
    def my_save(self, *args, **kwargs):
99
        user = self.get_user_in_request()
100
        self.clean_validated_data()
Florent Chehab's avatar
Florent Chehab committed
101
        self.my_pre_save()
102

103
104
105
        if self.moderation_required():
            if self.instance is None:  # we need to create the main model
                self.instance = super(
Florent Chehab's avatar
Florent Chehab committed
106
                    MyModelSerializer, self).save(*args, **kwargs)
107

108
            objs_pending_db = self.get_pending_models()
109

110
            self.clean_validated_data()  # Make that it is done...
111
112
            if len(objs_pending_db) > 0:
                pending_instance = objs_pending_db[0]
113
114
                pending_instance.updated_on = timezone.now()
                pending_instance.updated_by = user
115
116
117
118
                pending_instance.new_object = self.validated_data
            else:
                pending_instance = PendingModeration(
                    referenced_object=self.instance,
119
120
                    updated_by=user,
                    updated_on=timezone.now(),
121
122
                    new_object=self.validated_data
                )
123
            pending_instance.save()
124
125
126
            return self.instance

        else:
127

128
            moderated_and_updated = True
129
            if self.instance is None:
130
                self.set_model_attr_no_moder(moderated_and_updated)
Florent Chehab's avatar
Florent Chehab committed
131
                return super(MyModelSerializer, self).save(*args, **kwargs)
132
133
            else:
                # We check if we don't have any moderation pending
134
                objs_pending_db = self.get_pending_models()
135
                if len(objs_pending_db) > 0:
136
137
138
139
140
141
142
                    obj_pending_db = objs_pending_db[0]
                    self.clean_validated_data()  # Make that it is done...
                    if obj_pending_db.new_object == self.validated_data:
                        moderated_and_updated = False
                        self.validated_data['updated_by'] = obj_pending_db.updated_by
                        self.validated_data['updated_on'] = obj_pending_db.updated_on

143
144
                    objs_pending_db.delete()

145
                self.set_model_attr_no_moder(moderated_and_updated)
Florent Chehab's avatar
Florent Chehab committed
146
                return super(MyModelSerializer, self).save(*args, **kwargs)