Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

120

121

122

123

from django.conf import settings 

from django.db import models 

from rest_framework import serializers, viewsets 

from rest_framework.response import Response 

 

from backend_app.custom.mySerializerWithJSON import MySerializerWithJSON 

from backend_app.permissions.app_permissions import ReadOnly 

from backend_app.permissions.default import DEFAULT_VIEWSET_PERMISSIONS 

 

 

class BaseModel(models.Model): 

""" 

All models in the app inherits from this one. 

 

As of now, this model doesn't have any special fields. 

It is basically here to have a coherent naming convention. In fact some 

high level behaviors have been implemented in the corresponding Serializer and 

viewset. 

""" 

 

# Look at the documentation about config files to know more about this 

# https://rex-dri.gitlab.utc.fr/rex-dri/documentation/#/Application/Backend/moderation_and_versioning?id=model-level 

# http://localhost:5000/#/Application/Backend/moderation_and_versioning?id=model-level 

moderation_level = settings.DEFAULT_MODEL_MODERATION_LEVEL 

 

class Meta: 

abstract = True 

 

 

class BaseModelSerializer(MySerializerWithJSON): 

""" 

Serializer to go along the BaseModel model. This serializer make sure some 

relevant data is always returned. 

""" 

 

obj_info = serializers.SerializerMethodField() 

 

# For easier handling on the client side, we force an id field 

# this is useful when a model has a dedicated primary key 

id = serializers.SerializerMethodField() 

 

@classmethod 

def get_user_related_field(cls, user): 

""" 

Generic function to make sure we return only the pseudo and the id". 

:param user: user associated with object 

:return: dict 

""" 

if user is None: 

# In testing env or if data is not perfectly initialised 

return dict(user_id=None, user_goes_by=None) 

else: 

user_goes_by = ( 

"{} {}".format(user.first_name, user.last_name) 

if user.allow_sharing_personal_info 

else user.pseudo 

) 

return dict(user_id=user.pk, user_goes_by=user_goes_by) 

 

def get_obj_info(self, obj) -> dict: 

""" 

Serializer for the `obj_info` *dynamic* field. 

`obj` is required in the function definition, but it's not used. 

 

For all object return by the backend api, we add a custom `obj_info` 

field. The default value are chown below. 

 

This methods is overrided in EssentialModuleSerializer for 

a smarter behavior. 

""" 

return {"user_can_edit": False, "user_can_moderate": False, "versioned": False} 

 

def get_id(self, obj: BaseModel): 

""" 

Serializer for the id field. 

""" 

return obj.pk 

 

def get_user_from_request(self): 

""" 

Function to retrieve the user from the request 

""" 

return self.context["request"].user 

 

class Meta: 

model = BaseModel 

fields = ("obj_info", "id") 

 

 

class BaseModelViewSet(viewsets.ModelViewSet): 

""" 

Custom default viewset 

""" 

 

serializer_class = BaseModelSerializer 

permission_classes = ( 

DEFAULT_VIEWSET_PERMISSIONS & ReadOnly, 

) # ReadOnly or Override 

 

# We store the api endpoint route directly in the viewset classes 

# so that we can easily access them 

end_point_route = None 

 

def get_permissions(self): 

""" 

We override the permission getter to make sure we add the default 

app viewsets permissions 

""" 

return [p() for p in self.permission_classes] + [DEFAULT_VIEWSET_PERMISSIONS()] 

 

# Attribute that lists the fields that are expected to be preset in request.GET 

required_filterset_fields = tuple() 

 

def list(self, request, *args, **kwargs): 

""" 

Overrides the default list to enable required filterset_fields 

""" 

for field_name in self.required_filterset_fields: 

if field_name not in request.GET.keys(): 

return Response( 

"Missing get parameter `{}`".format(field_name), status=422 

) 

return super().list(request, args, kwargs)