You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

267 lines
7.8 KiB

from django.contrib.auth.models import User, Group
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_auth.registration.serializers import RegisterSerializer
from rest_auth.serializers import UserDetailsSerializer
from uuid import uuid4
from PIL import Image
from . import models, old_models
#custom_error = lambda x: ValidationError(dict(non_field_errors=x))
STATIC_FOLDER = 'data/static/'
LARGE_SIZE = 1080
MEDIUM_SIZE = 220
SMALL_SIZE = 110
def process_image(upload):
try:
pic = Image.open(upload)
except OSError:
raise serializers.ValidationError('Invalid image file.')
if pic.format == 'PNG':
ext = '.png'
elif pic.format == 'JPEG':
ext = '.jpg'
else:
raise serializers.ValidationError('Image must be a jpg or png.')
large = str(uuid4()) + ext
pic.thumbnail([LARGE_SIZE, LARGE_SIZE], Image.ANTIALIAS)
pic.save(STATIC_FOLDER + large)
medium = str(uuid4()) + ext
pic.thumbnail([MEDIUM_SIZE, MEDIUM_SIZE], Image.ANTIALIAS)
pic.save(STATIC_FOLDER + medium)
small = str(uuid4()) + ext
pic.thumbnail([SMALL_SIZE, SMALL_SIZE], Image.ANTIALIAS)
pic.save(STATIC_FOLDER + small)
return small, medium, large
class UserEmailField(serializers.ModelField):
def to_representation(self, obj):
return getattr(obj.user, 'email', obj.old_email)
def to_internal_value(self, data):
return serializers.EmailField().run_validation(data)
class AdminCardSerializer(serializers.ModelSerializer):
card_number = serializers.CharField()
class Meta:
model = models.Card
fields = '__all__'
read_only_fields = ['last_seen_at']
# member viewing other members
class OtherMemberSerializer(serializers.ModelSerializer):
class Meta:
model = models.Member
fields = ['id', 'preferred_name', 'last_name', 'status', 'current_start_date', 'photo_small', 'photo_large']
# member viewing his own details
class MemberSerializer(serializers.ModelSerializer):
photo = serializers.ImageField(write_only=True, required=False)
email = UserEmailField(serializers.EmailField)
phone = serializers.CharField()
street_address = serializers.CharField()
city = serializers.CharField()
postal_code = serializers.CharField()
class Meta:
model = models.Member
fields = '__all__'
read_only_fields = [
'id',
'is_director',
'is_instructor',
'status',
'expire_date',
'current_start_date',
'application_date',
'vetted_date',
'monthly_fees',
'photo_large',
'photo_medium',
'photo_small',
'user',
'old_email',
]
def update(self, instance, validated_data):
if instance.user:
instance.user.email = validated_data.get('email', instance.user.email)
instance.user.save()
else:
instance.old_email = validated_data.get('email', instance.old_email)
photo = validated_data.get('photo', None)
if photo:
small, medium, large = process_image(photo)
instance.photo_small = small
instance.photo_medium = medium
instance.photo_large = large
return super().update(instance, validated_data)
# admin viewing member details
class AdminMemberSerializer(MemberSerializer):
class Meta:
model = models.Member
fields = '__all__'
read_only_fields = [
'id',
'status',
'photo_large',
'photo_medium',
'photo_small',
'user',
'old_email',
]
# member viewing member list or search result
class SearchSerializer(serializers.Serializer):
q = serializers.CharField(write_only=True, max_length=64)
seq = serializers.IntegerField(write_only=True)
member = serializers.SerializerMethodField()
def get_member(self, obj):
serializer = OtherMemberSerializer(obj)
return serializer.data
# admin viewing search result
class AdminSearchSerializer(serializers.Serializer):
cards = serializers.SerializerMethodField()
member = serializers.SerializerMethodField()
def get_member(self, obj):
serializer = AdminMemberSerializer(obj)
return serializer.data
def get_cards(self, obj):
if obj.user:
queryset = obj.user.cards
else:
queryset = models.Card.objects.filter(member_id=obj.id)
serializer = AdminCardSerializer(data=queryset, many=True)
serializer.is_valid()
return serializer.data
class UserTrainingSerializer(serializers.ModelSerializer):
class Meta:
model = models.Training
exclude = ['user']
depth = 2
class UserSerializer(serializers.ModelSerializer):
training = UserTrainingSerializer(many=True)
member = MemberSerializer()
class Meta:
model = User
fields = ['id', 'username', 'member', 'transactions', 'cards', 'training', 'is_staff']
depth = 1
class TransactionSerializer(serializers.ModelSerializer):
class Meta:
model = models.Transaction
fields = '__all__'
class SessionDetailSerializer(serializers.ModelSerializer):
class Meta:
model = models.Training
exclude = ['user']
class SessionSerializer(serializers.ModelSerializer):
student_count = serializers.SerializerMethodField()
class Meta:
model = models.Session
fields = '__all__'
depth = 1
def get_student_count(self, obj):
return len(obj.students.all())
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Course
fields = '__all__'
class CourseDetailSerializer(serializers.ModelSerializer):
sessions = SessionSerializer(many=True)
class Meta:
model = models.Course
fields = '__all__'
depth = 1
class AdminCourseSerializer(serializers.ModelSerializer):
class Meta:
model = models.Course
fields = '__all__'
class RegistrationSerializer(RegisterSerializer):
first_name = serializers.CharField(max_length=32)
last_name = serializers.CharField(max_length=32)
existing_member = serializers.ChoiceField(['true', 'false'])
def custom_signup(self, request, user):
data = request.data
if data['existing_member'] == 'true':
old_members = old_models.Members.objects.using('old_portal')
try:
old_member = old_members.get(email=data['email'])
except old_models.Members.DoesNotExist:
user.delete()
raise ValidationError(dict(email='Unable to find email in old database.'))
member = models.Member.objects.get(id=old_member.id)
if member.user:
raise ValidationError(dict(email='Old member already claimed.'))
member.user = user
member.first_name = data['first_name']
member.last_name = data['last_name']
member.preferred_name = data['first_name']
member.save()
transactions = models.Transaction.objects.filter(member_id=member.id)
for t in transactions:
t.user = user
t.save()
cards = models.Card.objects.filter(member_id=member.id)
for c in cards:
c.user = user
c.save()
training = models.Training.objects.filter(member_id=member.id)
for t in training:
t.user = user
t.save()
else:
models.Member.objects.create(
user=user,
first_name=data['first_name'],
last_name=data['last_name'],
preferred_name=data['first_name'],
)