from django.contrib.auth.hashers import make_password, check_password from django.contrib.auth import get_user_model User = get_user_model() import uuid from django.db import IntegrityError from django.conf import settings from django.urls import reverse from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError from django.db import transaction from rest_framework import serializers from rest_framework_gis.serializers import GeoFeatureModelSerializer from sqlalchemy.sql.functions import mode from .models import Location, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, GifuAreas, RogUser, UserTracks, GoalImages, CheckinImages,CustomUser,NewEvent,NewEvent2, Team, NewCategory, Category, Entry, Member, TempUser,EntryMember from drf_extra_fields.fields import Base64ImageField #from django.contrib.auth.models import User from .models import CustomUser from django.contrib.auth import authenticate from .models import TestModel import logging from django.shortcuts import get_object_or_404 from django.utils import timezone from datetime import datetime, date logger = logging.getLogger(__name__) class LocationCatSerializer(serializers.ModelSerializer): class Meta: model=Location fields=['category',] class LocationSerializer(GeoFeatureModelSerializer): class Meta: model=Location geo_field='geom' fields="__all__" class Location_lineSerializer(GeoFeatureModelSerializer): class Meta: model=Location_line geo_field='geom' fields="__all__" class Location_polygonSerializer(GeoFeatureModelSerializer): class Meta: model=Location_polygon geo_field='geom' fields="__all__" class JPN_main_perfSerializer(serializers.ModelSerializer): class Meta: model=JpnAdminMainPerf fields=['id', 'adm0_en', 'adm0_ja', 'adm0_pcode', 'adm1_en', 'adm1_ja', 'adm1_pcode'] # class JPN_sub_perSerializer(serializers.ModelSerializer): # class Meta: # model=JpnSubPerf # fields=['id', 'adm0_en', 'adm0_ja', 'adm0_pcode', 'adm1_en', 'adm1_ja', 'adm1_pcode', 'adm2_ja', 'adm2_en', 'adm2_pcode'] # class JPN_perfSerializer(serializers.ModelSerializer): # class Meta: # model=JpnAdminPerf # fields=['id','et_id', 'et_right', 'et_left', 'adm2_l', 'adm1_l', 'adm0_l', 'adm0_r', 'adm1_r', 'adm2_r', 'admlevel'] class GifuAreaSerializer(serializers.ModelSerializer): class Meta: model= GifuAreas fields=['id', 'adm0_ja', 'adm0_pcode', 'adm1_en', 'adm1_ja', 'adm1_pcode', 'adm2_ja', 'adm2_en', 'adm2_pcode', 'area_nm'] class UserRegistrationSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, required=True, validators=[validate_password]) password2 = serializers.CharField(write_only=True, required=True, validators=[validate_password]) class Meta: model = CustomUser fields = ('email', 'password', 'password2', 'firstname', 'lastname', 'date_of_birth', 'female') extra_kwargs = { 'email': {'required': True}, 'firstname': {'required': True}, 'lastname': {'required': True}, 'date_of_birth': {'required': True}, } def validate(self, attrs): if attrs['password'] != attrs['password2']: raise serializers.ValidationError({"password": "Password fields didn't match."}) try: validate_password(attrs['password']) except ValidationError as e: raise serializers.ValidationError({"password": list(e.messages)}) return attrs def validate_email(self, value): if CustomUser.objects.filter(email=value).exists() or TempUser.objects.filter(email=value).exists(): raise serializers.ValidationError("この電子メールアドレスは既に使用されています。") return value def create(self, validated_data): raw_password = validated_data.get('password') # デバッグコード hashed_password = make_password(raw_password) print(f"Hashed password during registration: {hashed_password}") is_valid = check_password(raw_password, hashed_password) print(f"Password is valid during registration: {is_valid}") validated_data['password'] = hashed_password return super(UserRegistrationSerializer, self).create(validated_data) #validated_data['password'] = make_password(validated_data.get('password')) #return super(UserRegistrationSerializer, self).create(validated_data) # try: # with transaction.atomic(): # password = validated_data['password'].encode('utf-8').decode('utf-8') # # user = CustomUser.objects.create_user( # email=validated_data['email'], # password=password, # validated_data['password'], # firstname=validated_data['firstname'], # lastname=validated_data['lastname'], # date_of_birth=validated_data['date_of_birth'], # female=validated_data.get('female', False), # group='' # この値は必要に応じて変更してください # ) # logger.debug(f"Creating user with data: {validated_data}") # user.set_password(validated_data['password']) # user.save() # # return user # except ValidationError as e: # raise serializers.ValidationError({"password": list(e.messages)}) #class CreateUserSerializer(serializers.ModelSerializer): # class Meta: # model = CustomUser # fields = ('email', 'password') # extra_kwargs = {'password': {'write_only': True}} # # def create(self, validated_data): # user = CustomUser.objects.create_user(validated_data['email'],validated_data['password'], '大垣-初心者','','') # return user class TempUserRegistrationSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True) class Meta: model = TempUser fields = ('email', 'password', 'firstname', 'lastname', 'date_of_birth', 'female') def create(self, validated_data): # パスワードのハッシュ化はviewで行うので、ここではそのまま保存 return TempUser.objects.create(**validated_data) #validated_data['verification_code'] = str(uuid.uuid4()) #raw_password = validated_data.get('password') #hashed_password = make_password(raw_password) #validated_data['password'] = hashed_password #return TempUser.objects.create(**validated_data) class UserSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ('id','email', 'is_rogaining' ,'group', 'zekken_number', 'event_code', 'team_name') class GolaImageSerializer(serializers.ModelSerializer): goalimage = Base64ImageField(max_length=None, use_url=True) class Meta: model = GoalImages fields="__all__" def get_goalimage_url_old(self, car): request = self.context.get('request') photo_url = GoalImages.goalimage.url return request.build_absolute_uri(photo_url) def get_goalimage_url(self, obj): request = self.context.get('request') if request is None: logger.warning("Request not found in serializer context") return None try: photo_url = obj.goalimage.url absolute_url = request.build_absolute_uri(photo_url) logger.info(f"Generated URL for goalimage: {absolute_url}") return absolute_url except AttributeError as e: logger.error(f"Error generating URL for goalimage: {str(e)}") return None def to_representation(self, instance): representation = super().to_representation(instance) representation['goalimage_url'] = self.get_goalimage_url(instance) logger.debug(f"Serialized data: {representation}") return representation class CheckinImageSerializer(serializers.ModelSerializer): checkinimage = Base64ImageField(max_length=None, use_url=True) class Meta: model = CheckinImages fields="__all__" def get_checkinimage_url(self, car): request = self.context.get('request') photo_url = CheckinImages.checkinimage.url return request.build_absolute_uri(photo_url) class RogUserSerializer(serializers.ModelSerializer): class Meta: model = RogUser fields = ('id','user', 'paid',) class LoginUserSerializer(serializers.Serializer): #email = serializers.CharField() email = serializers.EmailField() password = serializers.CharField() def validate(self, data): email = data.get('email') password = data.get('password') if email and password: user = authenticate(username=email, password=password) if user: if user.is_active: return user raise serializers.ValidationError("User account is disabled.") else: # Check if the user exists try: user_obj = User.objects.get(email=email) raise serializers.ValidationError("Incorrect password.") except User.DoesNotExist: raise serializers.ValidationError("User with this email does not exist.") else: raise serializers.ValidationError("Must include 'email' and 'password'.") class UseractionsSerializer(serializers.ModelSerializer): user = UserSerializer(read_only=True) #location = LocationSerializer(read_only=True) location = serializers.RelatedField(source='Location', read_only=True) #location = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Useractions fields = ('id', 'user', 'location', 'wanttogo', 'like', 'checkin', 'order',) class UserDestinationSerializer(serializers.ModelSerializer): #user = UserSerializer(read_only=True) location = LocationSerializer(read_only=True) #location = serializers.RelatedField(source='Location', read_only=True) #location = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Useractions fields = ('id', 'user', 'location', 'wanttogo', 'like', 'checkin') class LocationEventNameSerializer(serializers.ModelSerializer): class Meta: model = Location fields = ('id', 'event_name',) class UserTracksSerializer(GeoFeatureModelSerializer): user_id = serializers.IntegerField() class Meta: model=UserTracks geo_field = 'geom' fields = ["user_id",] def create(self, validated_data): user_id = validated_data.pop("user_id", None) user = CustomUser.objects.get(id=user_id) return UserTracks.objects.create(user=user, **validated_data) class TestSerialiser(serializers.ModelSerializer): class Meta: model = TestModel fields = ('id', 'testbane', 'wanttogo', 'like', 'checkin') class ChangePasswordSerializer(serializers.Serializer): model = CustomUser """ Serializer for password change endpoint. """ old_password = serializers.CharField(required=True) new_password = serializers.CharField(required=True) class RegistrationSerializer(serializers.ModelSerializer): password2 = serializers.CharField(style={"input_type": "password"}, write_only=True) class Meta: model = CustomUser fields = ['email', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'password', 'password2'] extra_kwargs = { 'password': {'write_only': True} } def save(self): user = CustomUser(email=self.validated_data['email'], is_rogaining=self.validated_data['is_rogaining'], zekken_number=self.validated_data['zekken_number'], event_code=self.validated_data['event_code'], team_name=self.validated_data['team_name'], group=self.validated_data['group']) password = self.validated_data['password'] password2 = self.validated_data['password2'] if password != password2: raise serializers.ValidationError({'password': 'Passwords must match.'}) user.set_password(password) user.save() return user class NewCategorySerializer(serializers.ModelSerializer): class Meta: model = NewCategory fields = ['id','category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female'] #fields = ['id','category_name', 'category_number'] class NewEvent2Serializer(serializers.ModelSerializer): class Meta: model = NewEvent2 fields = ['id','event_name', 'start_datetime', 'end_datetime', 'deadlineDateTime', 'public', 'hour_3', 'hour_5', 'class_general','class_family','class_solo_male','class_solo_female'] class NewEventSerializer(serializers.ModelSerializer): class Meta: model = NewEvent fields = ['event_name', 'start_datetime', 'end_datetime'] class TeamSerializer(serializers.ModelSerializer): category = serializers.PrimaryKeyRelatedField(queryset=NewCategory.objects.all()) #category = serializers.IntegerField() #category = NewCategorySerializer(read_only=True) #category_id = serializers.PrimaryKeyRelatedField( # queryset=NewCategory.objects.all(), # source='category', # write_only=True #) owner = serializers.PrimaryKeyRelatedField(read_only=True) class Meta: model = Team fields = ['id','team_name', 'category', 'owner'] read_only_fields = ['id', 'owner'] def to_representation(self, instance): ret = super().to_representation(instance) if instance.category: ret['category'] = { 'id': instance.category.id, 'category_name': instance.category.category_name, 'category_number': instance.category.category_number, 'duration': instance.category.duration, 'num_of_member':instance.category.num_of_member, 'family':instance.category.family, 'female':instance.category.female } else: ret['category'] = None ret['owner'] = CustomUserSerializer(instance.owner).data return ret def validate_category(self, value): if not isinstance(value, NewCategory): raise serializers.ValidationError("Invalid category") return value #if not NewCategory.objects.filter(id=value).exists(): # raise serializers.ValidationError("Invalid category ID") #return value def create(self, validated_data): return Team.objects.create(**validated_data) #category_id = validated_data.pop('category') #category = get_object_or_404(NewCategory, id=category_id) #team = Team.objects.create(category=category, **validated_data) #team.category = category #return team #category = validated_data.pop('category') #team = Team.objects.create(category=category, **validated_data) #return team #logger.debug(f"Creating team with data: {validated_data}") #validated_data['owner'] = self.context['request'].user #return super().create(validated_data) def update(self, instance, validated_data): for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() return instance #if 'category' in validated_data: # category_id = validated_data.pop('category') # category = get_object_or_404(NewCategory, id=category_id) # instance.category = category #return super().update(instance, validated_data) #if 'category' in validated_data: # instance.category = validated_data.pop('category') #return super().update(instance, validated_data) class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = ['category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female'] class EntrySerializer(serializers.ModelSerializer): team = serializers.PrimaryKeyRelatedField(queryset=Team.objects.all()) event = serializers.PrimaryKeyRelatedField(queryset=NewEvent2.objects.all()) category = serializers.PrimaryKeyRelatedField(queryset=NewCategory.objects.all()) owner = serializers.PrimaryKeyRelatedField(read_only=True) date = serializers.DateTimeField(input_formats=['%Y-%m-%d']) zekken_number = serializers.IntegerField() #date = serializers.DateTimeField(default_timezone=timezone.get_current_timezone()) class Meta: model = Entry fields = ['id','team', 'event', 'category', 'date','zekken_number','owner','is_active', 'hasParticipated', 'hasGoaled'] read_only_fields = ['id','owner'] def validate_date(self, value): if isinstance(value, str): try: value = datetime.strptime(value, "%Y-%m-%d") except ValueError: raise serializers.ValidationError("Invalid date format. Use YYYY-MM-DD.") if isinstance(value, date): value = datetime.combine(value, datetime.min.time()) if timezone.is_naive(value): return timezone.make_aware(value, timezone.get_current_timezone()) return value #if isinstance(value, date): # # dateオブジェクトをdatetimeオブジェクトに変換 # value = datetime.combine(value, datetime.min.time()) #if timezone.is_naive(value): # return timezone.make_aware(value, timezone.get_current_timezone()) #return value def validate_team(self, value): if not value.members.exists(): raise serializers.ValidationError("チームにメンバーが登録されていません。") return value def validate_date(self, value): if isinstance(value, datetime): return value.date() return value def validate(self, data): team = data.get('team') event = data.get('event') category = data.get('category') entry_date = data.get('date') if isinstance(entry_date, datetime): entry_date = entry_date.date() elif isinstance(entry_date, str): entry_date = datetime.strptime(entry_date, "%Y-%m-%d").date() logger.debug("test-0") logger.debug(f"==== start:{event.start_datetime.date()} <= entry_date : {entry_date} <= end:{event.end_datetime.date()} ?? ====") if entry_date < event.start_datetime.date() or entry_date > event.end_datetime.date(): raise serializers.ValidationError(f"日付は{event.start_datetime.date()}から{event.end_datetime.date()}の間である必要があります。") logger.debug("test-1") try: logger.debug(f"Parsed data: team={team}, event={event}, category={category}, ") owner = self.context['request'].user zekken_number = data.get('zekken_number') logger.debug(f"entry_date={entry_date}, owner={owner}, zekken_number={zekken_number}") except Exception: raise serializers.ValidationError(f"何らかのエラーが発生しました") # Check if team, event, and category exist if not Team.objects.filter(id=team.id).exists(): raise serializers.ValidationError("指定されたチームは存在しません。") if not NewEvent2.objects.filter(id=event.id).exists(): raise serializers.ValidationError("指定されたイベントは存在しません。") if not NewCategory.objects.filter(id=category.id).exists(): raise serializers.ValidationError("指定されたカテゴリーは存在しません。") # Check for unique constraint if Entry.objects.filter(team=team, event=event, date__date=entry_date, owner=owner).exists(): raise serializers.ValidationError("既に登録済みです。") # Validate zekken_number if zekken_number is not None: if zekken_number <= 0: raise serializers.ValidationError("ゼッケン番号は正の整数である必要があります。") # if Entry.objects.filter(event=event, zekken_number=zekken_number).exists(): # raise serializers.ValidationError("このゼッケン番号は既に使用されています。") return data def to_internal_value(self, data): # dateフィールドが文字列で来た場合の処理 if 'date' in data and isinstance(data['date'], str): try: # 文字列をdatetimeオブジェクトに変換 data['date'] = datetime.strptime(data['date'], "%Y-%m-%d") except ValueError: raise serializers.ValidationError({"date": "無効な日付形式です。YYYY-MM-DD形式を使用してください。"}) return super().to_internal_value(data) def to_representation(self, instance): ret = super().to_representation(instance) ret['team'] = TeamSerializer(instance.team).data ret['event'] = NewEvent2Serializer(instance.event).data ret['category'] = NewCategorySerializer(instance.category).data ret['owner'] = CustomUserSerializer(instance.owner).data if isinstance(ret['date'], datetime): ret['date'] = ret['date'].date().isoformat() elif isinstance(ret['date'], date): ret['date'] = ret['date'].isoformat() return ret #if isinstance(ret['date'], datetime): # ret['date'] = ret['date'].date().isoformat() #return ret #def to_representation(self, instance): # ret = super().to_representation(instance) # ret['team'] = instance.team.team_name # ret['event'] = instance.event.event_name # ret['category'] = instance.category.category_name # ret['owner'] = instance.owner.email # return ret class CustomUserSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ['id','email', 'firstname', 'lastname', 'date_of_birth', 'female'] read_only_fields = ['id','email'] class TeamDetailSerializer(serializers.ModelSerializer): category = NewCategorySerializer(read_only=True) class Meta: model = Team fields = ['id', 'zekken_number', 'team_name', 'category'] class UserSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ['id','email', 'firstname', 'lastname', 'date_of_birth', 'female', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group'] read_only_fields = ('id', 'email') class UserUpdateSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ['firstname', 'lastname', 'date_of_birth', 'female'] extra_kwargs = {'email': {'read_only': True}} def update(self, instance, validated_data): for attr, value in validated_data.items(): setattr(instance, attr, value) instance.save() return instance class MemberCreationSerializer(serializers.Serializer): #email = serializers.EmailField() email = serializers.EmailField(allow_blank=True, required=False) firstname = serializers.CharField(required=False, allow_blank=True) lastname = serializers.CharField(required=False, allow_blank=True) date_of_birth = serializers.DateField(required=False) female = serializers.BooleanField(required=False) class MemberWithUserSerializer(serializers.ModelSerializer): user = UserSerializer(read_only=True) class Meta: model = Member fields = ['user', 'team'] class MemberSerializer(serializers.ModelSerializer): email = serializers.EmailField(write_only=True) firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True) lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True) date_of_birth = serializers.DateField(required=False, allow_null=True) female = serializers.BooleanField(required=False) class Meta: model = Member fields = ['id', 'email', 'firstname', 'lastname', 'date_of_birth', 'female'] def validate_firstname(self, value): return value or None def validate_lastname(self, value): return value or None def create(self, validated_data): email = validated_data.pop('email') team = self.context['team'] # 既存のユーザーを探すか、新しいユーザーを作成 user, created = CustomUser.objects.get_or_create(email=email) # ユーザーが新しく作成された場合のみ、追加情報を更新 if created: user.firstname = validated_data.get('firstname', '') user.lastname = validated_data.get('lastname', '') user.date_of_birth = validated_data.get('date_of_birth') user.female = validated_data.get('female', False) user.save() # メンバーを作成 member = Member.objects.create( user=user, team=team, firstname=validated_data.get('firstname'), lastname=validated_data.get('lastname'), date_of_birth=validated_data.get('date_of_birth'), female=validated_data.get('female', False) ) return member # メンバーを作成して返す #class MemberCreationSerializerreturn Member.objects.create(user=user, team=team) def update(self, instance, validated_data): user_data = validated_data.pop('user', {}) user = instance.user for attr, value in user_data.items(): setattr(user, attr, value) user.save() return super().update(instance, validated_data) def to_representation(self, instance): representation = super().to_representation(instance) representation['email'] = instance.user.email representation['firstname'] = instance.user.firstname representation['lastname'] = instance.user.lastname representation['date_of_birth'] = instance.user.date_of_birth representation['female'] = instance.user.female return representation class MemberSerializerOld(serializers.ModelSerializer): user = CustomUserSerializer(read_only=True) firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True) lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True) date_of_birth = serializers.DateField(required=False, allow_null=True) female = serializers.BooleanField(required=False) #team = TeamDetailSerializer(read_only=True) #email = serializers.EmailField(write_only=True, required=False) #firstname = serializers.CharField(write_only=True, required=False) #lastname = serializers.CharField(write_only=True, required=False) #date_of_birth = serializers.DateField(write_only=True, required=False) #female = serializers.BooleanField(write_only=True, required=False) class Meta: model = Member fields = ['id','email','firstname','lastname','date_of_birth','female'] #read_only_fields = ['id', 'team'] ''' def create(self, validated_data): team = validated_data['team'] email = validated_data.get('email') if email.startswith('dummy_'): user, _ = CustomUser.objects.get_or_create( email=email, defaults={**user_data, 'is_active': True} ) else: user, _ = CustomUser.objects.get_or_create( email=email, defaults={**user_data, 'is_active': False} ) member = Member.objects.create(user=user, **validated_data) return member ''' def create(self, validated_data): email = validated_data.pop('email') team = self.context['team'] # 既存のユーザーを探すか、新しいユーザーを作成 user, created = CustomUser.objects.get_or_create(email=email) # メンバーを作成 member = Member.objects.create( user=user, team=team, firstname=validated_data.get('firstname', ''), lastname=validated_data.get('lastname', ''), date_of_birth=validated_data.get('date_of_birth'), female=validated_data.get('female', False) ) return member def update(self, instance, validated_data): user_data = validated_data.pop('user', {}) user = instance.user for attr, value in user_data.items(): setattr(user, attr, value) user.save() return super().update(instance, validated_data) #if user.email.startswith('dummy_'): # dummy_ で始まるメールアドレスの場合のみ更新 # for attr, value in user_data.items(): # setattr(user, attr, value) # user.save() #else: # raise serializers.ValidationError("このユーザーの情報は更新できません。") #return super().update(instance, validated_data) def to_representation(self, instance): representation = super().to_representation(instance) representation['email'] = instance.user.email return representation ''' def to_representation(self, instance): representation = super().to_representation(instance) user_data = representation['user'] return { 'id': representation['id'], 'email': user_data['email'], 'firstname': user_data['firstname'], 'lastname': user_data['lastname'], 'date_of_birth': user_data['date_of_birth'], 'female': user_data['female'], 'team': representation['team'] } ''' class EntryMemberSerializer(serializers.ModelSerializer): class Meta: model = EntryMember fields = ['id', 'entry', 'member', 'is_temporary'] class TempUserSerializer(serializers.ModelSerializer): class Meta: model = TempUser #fields = ['id','email', 'password', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'firstname', 'lastname', 'date_of_birth', 'female', 'verification_code', 'created_at', 'expires_at'] fields = ['email', 'password', 'firstname', 'lastname', 'date_of_birth', 'female', 'verification_code'] class EntryCreationSerializer(serializers.Serializer): owner_email = serializers.EmailField() event_name = serializers.CharField() category_name = serializers.CharField() team_name = serializers.CharField() zekken_number = serializers.CharField() date = serializers.DateField() members = serializers.ListField(child=serializers.DictField()) def create(self, validated_data): owner = CustomUser.objects.get(email=validated_data['owner_email']) event = NewEvent2.objects.get(event_name=validated_data['event_name']) category = NewCategory.objects.get(category_name=validated_data['category_name']) # Create or get team team, _ = Team.objects.get_or_create( zekken_number=validated_data['zekken_number'], category=category, defaults={'team_name': validated_data['team_name'], 'owner': owner} ) # Create or update entry entry, _ = Entry.objects.update_or_create( owner=owner, team=team, event=event, date=validated_data['date'], defaults={'category': category} ) # Process members for member_data in validated_data['members']: user, created = CustomUser.objects.get_or_create( email=member_data.get('email'), defaults={ 'firstname': member_data['firstname'], 'lastname': member_data['lastname'], 'date_of_birth': member_data['date_of_birth'] } ) if created: TempUser.objects.create( email=user.email, firstname=user.firstname, lastname=user.lastname, date_of_birth=user.date_of_birth ) # Send invitation email here member, _ = NewMember.objects.get_or_create( user=user, team=team, defaults={'is_temporary': created} ) EntryMember.objects.get_or_create(entry=entry, member=member) return entry class PasswordResetRequestSerializer(serializers.Serializer): email = serializers.EmailField() class PasswordResetConfirmSerializer(serializers.Serializer): new_password = serializers.CharField(write_only=True) confirm_password = serializers.CharField(write_only=True) def validate(self, data): if data['new_password'] != data['confirm_password']: raise serializers.ValidationError("Passwords do not match") validate_password(data['new_password']) return data class UserLastGoalTimeSerializer(serializers.Serializer): user_email = serializers.EmailField() last_goal_time = serializers.DateTimeField()