Commit aebf1936d2eafa75bcd2f265d2a2477d0f996f3e

Authored by Andrew Buss
1 parent 646e7b1d8d
Exists in master

remove hide_reason from flashcard serializer

Showing 1 changed file with 5 additions and 4 deletions Inline Diff

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