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

124

125

126

from django.core.validators import MaxValueValidator, MinValueValidator 

from django.db import models 

from django_filters.rest_framework import DjangoFilterBackend 

from rest_framework.permissions import BasePermission 

from django_filters import rest_framework as filters 

 

from backend_app.models.abstract.essentialModule import ( 

EssentialModule, 

EssentialModuleSerializer, 

EssentialModuleViewSet, 

) 

from backend_app.models.exchange import Exchange 

from backend_app.models.university import University 

from backend_app.permissions.app_permissions import ReadOnly, IsStaff, NoDelete, NoPost 

from backend_app.permissions.moderation import ModerationLevels 

from backend_app.serializers import ExchangeSerializer 

from backend_app.utils import CustomPagination 

 

 

class ExchangeFeedback(EssentialModule): 

moderation_level = ModerationLevels.DEPENDING_ON_SITE_SETTINGS 

exchange = models.OneToOneField( 

Exchange, 

on_delete=models.CASCADE, 

related_name="feedbacks", 

primary_key=True, 

null=False, 

default=0, 

) 

general_comment = models.TextField(null=True, max_length=1500) 

academical_level_appreciation = models.IntegerField( 

default=0, validators=[MinValueValidator(-5), MaxValueValidator(5)] 

) 

foreign_student_welcome = models.IntegerField( 

default=0, validators=[MinValueValidator(-5), MaxValueValidator(5)] 

) 

cultural_interest = models.IntegerField( 

default=0, validators=[MinValueValidator(-5), MaxValueValidator(5)] 

) 

 

# A bit of denormalization (managed by signals) 

university = models.ForeignKey(University, on_delete=models.PROTECT, null=True) 

 

# Field to tell that the instance hasn't been edited as of now 

untouched = models.BooleanField(default=True, null=False) 

 

 

class ExchangeFeedbackSerializer(EssentialModuleSerializer): 

check_obj_permissions_for_edit = True 

 

exchange = ExchangeSerializer(read_only=True) 

 

def update(self, instance, validated_data): 

instance.untouched = False 

return super().update(instance, validated_data) 

 

class Meta: 

model = ExchangeFeedback 

fields = EssentialModuleSerializer.Meta.fields + ( 

"university", 

"exchange", 

"general_comment", 

"academical_level_appreciation", 

"foreign_student_welcome", 

"cultural_interest", 

"untouched", 

) 

read_only_fields = ("university", "exchange", "untouched") 

 

 

class ExchangePermission(BasePermission): 

""" 

Permission that checks that the requester is the student concern by the exchange. 

""" 

 

def has_object_permission(self, request, view, obj): 

exchange = obj.exchange 

if exchange.student is None: 

return False 

return request.user.pk == obj.exchange.student.pk 

 

 

class CharInFilter(filters.BaseInFilter, filters.CharFilter): 

pass 

 

 

class ExchangeFeedbackFilter(filters.FilterSet): 

exchange__student_major_in = CharInFilter( 

field_name="exchange__student_major", lookup_expr="in" 

) 

exchange__student_minor_in = CharInFilter( 

field_name="exchange__student_minor", lookup_expr="in" 

) 

 

class Meta: 

model = ExchangeFeedback 

fields = ["exchange__student_major_in", "exchange__student_minor_in"] 

 

 

class ExchangeFeedbackFilterBackend(DjangoFilterBackend): 

filterset_base = ExchangeFeedbackFilter 

 

 

class ExchangeFeedbackViewSet(EssentialModuleViewSet): 

permission_classes = ( 

NoDelete & NoPost & (ReadOnly | IsStaff | ExchangePermission), 

) 

queryset = ( 

ExchangeFeedback.objects.filter( 

exchange__unlinked=False 

) # only display linked instances 

.order_by("-exchange__year", "exchange__semester", "exchange_id") 

.select_related("exchange", "updated_by", "moderated_by", "exchange__student") 

.prefetch_related( 

"exchange__exchange_courses", 

"exchange__exchange_courses__course_feedback", 

"exchange__exchange_courses__course_feedback__updated_by", 

"exchange__exchange_courses__course_feedback__moderated_by", 

) 

) 

serializer_class = ExchangeFeedbackSerializer 

end_point_route = "exchangeFeedbacks" 

filterset_fields = ("university", "untouched") 

filter_backends = (filters.DjangoFilterBackend, ExchangeFeedbackFilterBackend) 

required_filterset_fields = ("university",) 

pagination_class = CustomPagination