Commit 55c7345264cf83d31acc0e9ffa457b0694404bea

Authored by Andrew Buss
1 parent 390189eb63
Exists in master

send floats for score

Showing 1 changed file with 2 additions and 3 deletions Inline Diff

flashcards/serializers.py View file @ 55c7345
from json import dumps, loads 1 1 from json import dumps, loads
2 2
from django.utils.datetime_safe import datetime 3 3 from django.utils.datetime_safe import datetime
from django.utils.timezone import now 4 4 from django.utils.timezone import now
from flashcards.models import Section, LecturePeriod, User, Flashcard, UserFlashcard, UserFlashcardQuiz 5 5 from flashcards.models import Section, LecturePeriod, User, Flashcard, UserFlashcard, UserFlashcardQuiz
from flashcards.validators import FlashcardMask, OverlapIntervalException 6 6 from flashcards.validators import FlashcardMask, OverlapIntervalException
from rest_framework import serializers 7 7 from rest_framework import serializers
from rest_framework.fields import EmailField, BooleanField, CharField, IntegerField, DateTimeField, empty, \ 8 8 from rest_framework.fields import EmailField, BooleanField, CharField, IntegerField, DateTimeField, empty, \
SerializerMethodField 9 9 SerializerMethodField, FloatField
from rest_framework.serializers import ModelSerializer, Serializer, PrimaryKeyRelatedField, ListField 10 10 from rest_framework.serializers import ModelSerializer, Serializer, PrimaryKeyRelatedField, ListField
from rest_framework.validators import UniqueValidator 11 11 from rest_framework.validators import UniqueValidator
from flashy.settings import QUARTER_END, QUARTER_START 12 12 from flashy.settings import QUARTER_END, QUARTER_START
13 13
14 14
class EmailSerializer(Serializer): 15 15 class EmailSerializer(Serializer):
email = EmailField(required=True) 16 16 email = EmailField(required=True)
17 17
18 18
class EmailPasswordSerializer(EmailSerializer): 19 19 class EmailPasswordSerializer(EmailSerializer):
password = CharField(required=True) 20 20 password = CharField(required=True)
21 21
22 22
class RegistrationSerializer(EmailPasswordSerializer): 23 23 class RegistrationSerializer(EmailPasswordSerializer):
email = EmailField(required=True, validators=[UniqueValidator(queryset=User.objects.all())]) 24 24 email = EmailField(required=True, validators=[UniqueValidator(queryset=User.objects.all())])
25 25
26 26
class PasswordResetRequestSerializer(EmailSerializer): 27 27 class PasswordResetRequestSerializer(EmailSerializer):
def validate_email(self, value): 28 28 def validate_email(self, value):
try: 29 29 try:
User.objects.get(email=value) 30 30 User.objects.get(email=value)
return value 31 31 return value
except User.DoesNotExist: 32 32 except User.DoesNotExist:
raise serializers.ValidationError('No user exists with that email') 33 33 raise serializers.ValidationError('No user exists with that email')
34 34
35 35
class PasswordResetSerializer(Serializer): 36 36 class PasswordResetSerializer(Serializer):
new_password = CharField(required=True, allow_blank=False) 37 37 new_password = CharField(required=True, allow_blank=False)
uid = IntegerField(required=True) 38 38 uid = IntegerField(required=True)
token = CharField(required=True) 39 39 token = CharField(required=True)
40 40
def validate_uid(self, value): 41 41 def validate_uid(self, value):
try: 42 42 try:
User.objects.get(id=value) 43 43 User.objects.get(id=value)
return value 44 44 return value
except User.DoesNotExist: 45 45 except User.DoesNotExist:
raise serializers.ValidationError('Could not verify reset token') 46 46 raise serializers.ValidationError('Could not verify reset token')
47 47
48 48
class UserUpdateSerializer(Serializer): 49 49 class UserUpdateSerializer(Serializer):
old_password = CharField(required=False) 50 50 old_password = CharField(required=False)
new_password = CharField(required=False, allow_blank=False) 51 51 new_password = CharField(required=False, allow_blank=False)
confirmation_key = CharField(required=False) 52 52 confirmation_key = CharField(required=False)
# reset_token = CharField(required=False) 53 53 # reset_token = CharField(required=False)
54 54
def validate(self, data): 55 55 def validate(self, data):
if 'new_password' in data and 'old_password' not in data: 56 56 if 'new_password' in data and 'old_password' not in data:
raise serializers.ValidationError('old_password is required to set a new_password') 57 57 raise serializers.ValidationError('old_password is required to set a new_password')
return data 58 58 return data
59 59
60 60
class Password(Serializer): 61 61 class Password(Serializer):
email = EmailField(required=True) 62 62 email = EmailField(required=True)
password = CharField(required=True) 63 63 password = CharField(required=True)
64 64
65 65
class LecturePeriodSerializer(ModelSerializer): 66 66 class LecturePeriodSerializer(ModelSerializer):
class Meta: 67 67 class Meta:
model = LecturePeriod 68 68 model = LecturePeriod
exclude = 'id', 'section' 69 69 exclude = 'id', 'section'
70 70
71 71
class SectionSerializer(ModelSerializer): 72 72 class SectionSerializer(ModelSerializer):
lecture_times = CharField() 73 73 lecture_times = CharField()
short_name = CharField() 74 74 short_name = CharField()
long_name = CharField() 75 75 long_name = CharField()
76 76
class Meta: 77 77 class Meta:
model = Section 78 78 model = Section
79 79
80 80
class DeepSectionSerializer(SectionSerializer): 81 81 class DeepSectionSerializer(SectionSerializer):
lectures = LecturePeriodSerializer(source='lectureperiod_set', many=True, read_only=True) 82 82 lectures = LecturePeriodSerializer(source='lectureperiod_set', many=True, read_only=True)
83 83
84 84
class UserSerializer(ModelSerializer): 85 85 class UserSerializer(ModelSerializer):
email = EmailField(required=False) 86 86 email = EmailField(required=False)
sections = SectionSerializer(many=True) 87 87 sections = SectionSerializer(many=True)
is_confirmed = BooleanField() 88 88 is_confirmed = BooleanField()
89 89
class Meta: 90 90 class Meta:
model = User 91 91 model = User
fields = ("sections", "email", "is_confirmed", "last_login", "date_joined") 92 92 fields = ("sections", "email", "is_confirmed", "last_login", "date_joined")
93 93
94 94
class MaskFieldSerializer(serializers.Field): 95 95 class MaskFieldSerializer(serializers.Field):
default_error_messages = { 96 96 default_error_messages = {
'max_length': 'Ensure this field has no more than {max_length} characters.', 97 97 'max_length': 'Ensure this field has no more than {max_length} characters.',
'interval': 'Ensure this field has valid intervals.', 98 98 'interval': 'Ensure this field has valid intervals.',
'overlap': 'Ensure this field does not have overlapping intervals.' 99 99 'overlap': 'Ensure this field does not have overlapping intervals.'
} 100 100 }
101 101
def to_representation(self, value): 102 102 def to_representation(self, value):
return map(list, self._make_mask(value)) 103 103 return map(list, self._make_mask(value))
104 104
def to_internal_value(self, value): 105 105 def to_internal_value(self, value):
if not isinstance(value, list): 106 106 if not isinstance(value, list):
value = loads(value) 107 107 value = loads(value)
return self._make_mask(value) 108 108 return self._make_mask(value)
109 109
def _make_mask(self, data): 110 110 def _make_mask(self, data):
try: 111 111 try:
mask = FlashcardMask(data) 112 112 mask = FlashcardMask(data)
except ValueError: 113 113 except ValueError:
raise serializers.ValidationError("Invalid JSON for MaskField") 114 114 raise serializers.ValidationError("Invalid JSON for MaskField")
except TypeError: 115 115 except TypeError:
raise serializers.ValidationError("Invalid data for MaskField.") 116 116 raise serializers.ValidationError("Invalid data for MaskField.")
except OverlapIntervalException: 117 117 except OverlapIntervalException:
raise serializers.ValidationError("Invalid intervals for MaskField data.") 118 118 raise serializers.ValidationError("Invalid intervals for MaskField data.")
if len(mask) > 32: 119 119 if len(mask) > 32:
raise serializers.ValidationError("Too many intervals in the mask.") 120 120 raise serializers.ValidationError("Too many intervals in the mask.")
return mask 121 121 return mask
122 122
123 123
class FlashcardSerializer(ModelSerializer): 124 124 class FlashcardSerializer(ModelSerializer):
is_hidden = SerializerMethodField() 125 125 is_hidden = SerializerMethodField()
is_in_deck = SerializerMethodField() 126 126 is_in_deck = SerializerMethodField()
# hide_reason = CharField(read_only=True) 127 127 # hide_reason = CharField(read_only=True)
material_date = DateTimeField(default=now) 128 128 material_date = DateTimeField(default=now)
mask = MaskFieldSerializer(allow_null=True) 129 129 mask = MaskFieldSerializer(allow_null=True)
score = IntegerField(read_only=True) 130 130 score = FloatField(read_only=True)
131
132 131
def validate_material_date(self, value): 133 132 def validate_material_date(self, value):
# TODO: make this dynamic 134 133 # TODO: make this dynamic
if QUARTER_START <= value <= QUARTER_END: 135 134 if QUARTER_START <= value <= QUARTER_END:
return value 136 135 return value
else: 137 136 else:
raise serializers.ValidationError("Material date is outside allowed range for this quarter") 138 137 raise serializers.ValidationError("Material date is outside allowed range for this quarter")
139 138
def validate_pushed(self, value): 140 139 def validate_pushed(self, value):
if value > datetime.now(): 141 140 if value > datetime.now():
raise serializers.ValidationError("Invalid creation date for the Flashcard") 142 141 raise serializers.ValidationError("Invalid creation date for the Flashcard")
return value 143 142 return value
144 143
def validate_mask(self, value): 145 144 def validate_mask(self, value):
if value is None: 146 145 if value is None:
return None 147 146 return None
if len(self.initial_data['text']) < value.max_offset(): 148 147 if len(self.initial_data['text']) < value.max_offset():
raise serializers.ValidationError("Mask out of bounds") 149 148 raise serializers.ValidationError("Mask out of bounds")
return value 150 149 return value
151 150
def get_is_hidden(self, obj): 152 151 def get_is_hidden(self, obj):
if 'user' not in self.context: return False 153 152 if 'user' not in self.context: return False
return obj.is_hidden_from(self.context['user']) 154 153 return obj.is_hidden_from(self.context['user'])
155 154
def get_is_in_deck(self, obj): 156 155 def get_is_in_deck(self, obj):
if 'user' not in self.context: return False 157 156 if 'user' not in self.context: return False
return obj.is_in_deck(self.context['user']) 158 157 return obj.is_in_deck(self.context['user'])
159 158
class Meta: 160 159 class Meta:
model = Flashcard 161 160 model = Flashcard
exclude = 'author', 'previous' 162 161 exclude = 'author', 'previous'
163 162
164 163
class FlashcardUpdateSerializer(serializers.Serializer): 165 164 class FlashcardUpdateSerializer(serializers.Serializer):
text = CharField(max_length=255, required=False) 166 165 text = CharField(max_length=255, required=False)
material_date = DateTimeField(required=False) 167 166 material_date = DateTimeField(required=False)
mask = MaskFieldSerializer(required=False) 168 167 mask = MaskFieldSerializer(required=False)
169 168
def validate_material_date(self, date): 170 169 def validate_material_date(self, date):
if date > QUARTER_END: 171 170 if date > QUARTER_END:
raise serializers.ValidationError("Invalid material_date for the flashcard") 172 171 raise serializers.ValidationError("Invalid material_date for the flashcard")
return date 173 172 return date
174 173
def validate(self, attrs): 175 174 def validate(self, attrs):
# Make sure that at least one of the attributes was passed in 176 175 # Make sure that at least one of the attributes was passed in
if not any(i in attrs for i in ['material_date', 'text', 'mask']): 177 176 if not any(i in attrs for i in ['material_date', 'text', 'mask']):
raise serializers.ValidationError("No new value passed in") 178 177 raise serializers.ValidationError("No new value passed in")
return attrs 179 178 return attrs
180 179
181 180
class QuizRequestSerializer(serializers.Serializer): 182 181 class QuizRequestSerializer(serializers.Serializer):
sections = ListField(child=IntegerField(min_value=1), required=False) 183 182 sections = ListField(child=IntegerField(min_value=1), required=False)
material_date_begin = DateTimeField(default=QUARTER_START) 184 183 material_date_begin = DateTimeField(default=QUARTER_START)
material_date_end = DateTimeField(default=QUARTER_END) 185 184 material_date_end = DateTimeField(default=QUARTER_END)
186 185
def update(self, instance, validated_data): 187 186 def update(self, instance, validated_data):
pass 188 187 pass
189 188
def create(self, validated_data): 190 189 def create(self, validated_data):
return validated_data 191 190 return validated_data
192 191
def validate_material_date_begin(self, value): 193 192 def validate_material_date_begin(self, value):
if QUARTER_START <= value <= QUARTER_END: 194 193 if QUARTER_START <= value <= QUARTER_END:
return value 195 194 return value
raise serializers.ValidationError("Invalid begin date for the flashcard range") 196 195 raise serializers.ValidationError("Invalid begin date for the flashcard range")
197 196
def validate_material_date_end(self, value): 198 197 def validate_material_date_end(self, value):
if QUARTER_START <= value <= QUARTER_END: 199 198 if QUARTER_START <= value <= QUARTER_END:
return value 200 199 return value
raise serializers.ValidationError("Invalid end date for the flashcard range") 201 200 raise serializers.ValidationError("Invalid end date for the flashcard range")
202 201
def validate_sections(self, value): 203 202 def validate_sections(self, value):
if value is None: 204 203 if value is None:
return Section.objects.all() 205 204 return Section.objects.all()
section_filter = Section.objects.filter(pk__in=value) 206 205 section_filter = Section.objects.filter(pk__in=value)
if not section_filter.exists(): 207 206 if not section_filter.exists():
raise serializers.ValidationError("Those aren't valid sections") 208 207 raise serializers.ValidationError("Those aren't valid sections")
return value 209 208 return value
210 209
def validate(self, attrs): 211 210 def validate(self, attrs):
if attrs['material_date_begin'] > attrs['material_date_end']: 212 211 if attrs['material_date_begin'] > attrs['material_date_end']:
raise serializers.ValidationError("Invalid range") 213 212 raise serializers.ValidationError("Invalid range")
if 'sections' not in attrs: 214 213 if 'sections' not in attrs: