Basic release 1-Aug-2024

This commit is contained in:
2024-08-01 07:51:52 +00:00
parent 49b3ee7342
commit bc74b14cbc
10 changed files with 500 additions and 86 deletions

View File

@ -1,3 +1,4 @@
import requests
from rest_framework import serializers
from django.db import IntegrityError
from django.urls import reverse
@ -158,6 +159,7 @@ def update_user_detail(request, user_id):
setattr(user, field, data[field])
new_value = getattr(user, field)
if old_value != new_value:
logger.debug(f"{field}: {old_value} -> {new_value}")
updated_fields.append(f"{field}: {old_value} -> {new_value}")
logger.debug(f"Fields to be updated: {updated_fields}")
@ -167,6 +169,12 @@ def update_user_detail(request, user_id):
logger.info(f"User {user_id} updated. Changed fields: {', '.join(updated_fields)}")
# 更新されたUserデータを使用して関連するMemberのデータを更新
members = Member.objects.filter(user=user)
for member in members:
member.is_temporary = False
member.save()
serializer = CustomUserSerializer(user)
return Response(serializer.data, status=status.HTTP_200_OK)
@ -832,20 +840,8 @@ class NewEventListView(generics.ListAPIView):
serializer_class = NewEventSerializer
permission_classes = [IsAuthenticated]
def update_external_system(zekken_number, event_code, team_name, class_name, password):
api_url = f"{settings.FRONTEND_URL}/gifuroge/update_team_name"
data = {
"zekken_number": zekken_number,
"new_team_name": team_name,
"event_code": event_code
}
try:
response = requests.post(api_url, json=data)
response.raise_for_status()
return True
except requests.RequestException as e:
logger.error(f"Failed to update external system. Error: {str(e)}")
return False
class TeamViewSet(viewsets.ModelViewSet):
serializer_class = TeamSerializer
@ -855,6 +851,8 @@ class TeamViewSet(viewsets.ModelViewSet):
return Team.objects.filter(owner=self.request.user)
def perform_create(self, serializer):
logger.info(f"Creating new team for user: {self.request.user.email}")
with transaction.atomic():
category = serializer.validated_data['category']
@ -864,12 +862,12 @@ class TeamViewSet(viewsets.ModelViewSet):
category.save()
category.refresh_from_db() # F() 式の結果を評価
serializer.save(owner=self.request.user, zekken_number=zekken_number)
team = self.get_object()
team = serializer.save(owner=self.request.user, zekken_number=zekken_number)
logger.info(f"Team created successfully: {team.id}")
# 外部システムの更新
success = update_external_system(
success = self.register_team(
team.owner,
team.zekken_number,
team.owner.event_code,
team.team_name,
@ -877,21 +875,93 @@ class TeamViewSet(viewsets.ModelViewSet):
team.owner.password
)
if not success:
logger.error("Failed to register external system")
raise serializers.ValidationError("外部システムの更新に失敗しました。")
logger.info("External system register successfully")
def register_team(self, owner,zekken_number,event_code,team_name,category_name,password):
logger.info(f"register_team ==> zekken_number={zekken_number},event_code={event_code},team_name={team_name},category_name={category_name},password={password}")
api_url = f"{settings.FRONTEND_URL}/gifuroge/register_team"
user = owner
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"zekken_number": zekken_number,
"event_code": event_code,
"team_name": team_name,
"class_name": category_name,
"password": password # パスワードの扱いに注意が必要です
}
try:
response = requests.post(api_url,headers=headers,data=data)
response.raise_for_status()
logger.info(f"Team registered successfully for team {team_name}")
return True
except requests.RequestException as e:
logger.error(f"Failed to register team for entry {entry.id}. Error: {str(e)}")
# エラーが発生しても、エントリー自体は作成されています
# 必要に応じて、ここでエラーハンドリングを追加できます
return False
def destroy(self, request, *args, **kwargs):
team = self.get_object()
if team.members.exists():
return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
return Response(
{
"error": "チームにメンバーが残っているため削除できません。",
"error_code": "TEAM_HAS_MEMBERS"
},
status=status.HTTP_400_BAD_REQUEST
)
#return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
return super().destroy(request, *args, **kwargs)
def update_external_system(zekken_number, event_code, team_name, class_name, password):
api_url = f"{settings.FRONTEND_URL}/gifuroge/update_team_name"
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
data = {
"zekken_number": zekken_number,
"new_team_name": team_name,
"event_code": event_code,
}
try:
response = requests.post(api_url,headers=headers, data=data)
response.raise_for_status()
return True
except requests.RequestException as e:
logger.error(f"Failed to update external system. Error: {str(e)}")
return False
def update(self, request, *args, **kwargs):
try:
return super().update(request, *args, **kwargs)
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
instance._prefetched_objects_cache = {}
return Response(serializer.data)
except Exception as e:
return Response({"error": "更新に失敗しました。競合が発生した可能性があります。"}, status=status.HTTP_409_CONFLICT)
# def update(self, request, *args, **kwargs):
# try:
# return super().update(request, *args, **kwargs)
# except Exception as e:
# return Response({"error": "更新に失敗しました。競合が発生した可能性があります。"}, status=status.HTTP_409_CONFLICT)
def perform_update(self, serializer):
with transaction.atomic():
team = serializer.save()
@ -906,7 +976,8 @@ class TeamViewSet(viewsets.ModelViewSet):
)
if not success:
raise serializers.ValidationError("外部システムの更新に失敗しました。")
else:
print("岐阜ロゲシステム更新に成功")
@action(detail=True, methods=['post'])
def copy(self, request, pk=None):
@ -1004,27 +1075,6 @@ class EntryViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
def register_team(self, entry):
api_url = f"{settings.FRONTEND_URL}/gifuroge/register_team"
user = self.request.user
data = {
"zekken_number": entry.team.zekken_number,
"event_code": entry.event.event_code,
"team_name": entry.team.team_name,
"class_name": entry.category.category_name,
"password": user.password # パスワードの扱いに注意が必要です
}
try:
response = requests.post(api_url, data=data)
response.raise_for_status()
logger.info(f"Team registered successfully for entry {entry.id}")
except requests.RequestException as e:
logger.error(f"Failed to register team for entry {entry.id}. Error: {str(e)}")
# エラーが発生しても、エントリー自体は作成されています
# 必要に応じて、ここでエラーハンドリングを追加できます
def update(self, request, *args, **kwargs):
logger.info(f"Update method called for Entry with ID: {kwargs.get('pk')}")
@ -1074,7 +1124,7 @@ class EntryViewSet(viewsets.ModelViewSet):
class MemberViewSet(viewsets.ModelViewSet):
#serializer_class = MemberSerializer
serializer_class = MemberSerializer
permission_classes = [permissions.IsAuthenticated,IsTeamOwner]
def get_serializer_class(self):
@ -1086,12 +1136,64 @@ class MemberViewSet(viewsets.ModelViewSet):
team_id = self.kwargs['team_id']
return Member.objects.filter(team_id=team_id)
@action(detail=False, methods=['DELETE'])
def destroy_all(self, request, team_id=None):
team = Team.objects.get(id=team_id)
# チームのオーナーかどうかを確認
if team.owner != request.user:
return Response({"error": "チームのオーナーのみがメンバーを一括削除できます。"}, status=status.HTTP_403_FORBIDDEN)
# 確認パラメータをチェック
confirm = request.query_params.get('confirm', '').lower()
if confirm != 'true':
return Response({"error": "確認パラメータが必要です。'?confirm=true'を追加してください。"}, status=status.HTTP_400_BAD_REQUEST)
try:
with transaction.atomic():
# オーナー以外のすべてのメンバーを削除
#deleted_count = Member.objects.filter(team=team).exclude(user=team.owner).delete()[0]
deleted_count = Member.objects.filter(team=team).delete()[0]
return Response({
"message": f"{deleted_count}人のメンバーが削除されました。",
"deleted_count": deleted_count
}, status=status.HTTP_200_OK)
except Exception as e:
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
team = instance.team
# チームのオーナーかどうかを確認
if team.owner != request.user:
return Response({"error": "チームのオーナーのみがメンバーを削除できます。"}, status=status.HTTP_403_FORBIDDEN)
# オーナー自身は削除できないようにする
#if instance.user == team.owner:
# return Response({"error": "チームのオーナーは削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT)
def create(self, request, *args, **kwargs):
logger.info(f"Attempting to create new member for team: {self.kwargs['team_id']}")
logger.debug(f"Received data: {request.data}")
team = Team.objects.get(id=self.kwargs['team_id'])
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
#serializer = self.get_serializer(data=request.data)
serializer = self.get_serializer(data=request.data, context={'team': team})
try:
serializer.is_valid(raise_exception=True)
except serializers.ValidationError as e:
logger.error(f"Validation error: {e.detail}")
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
email = serializer.validated_data.get('email', '')
logger.info(f"Processing member with email: {email}")
user_data = {
'firstname': serializer.validated_data.get('firstname', ''),
@ -1100,40 +1202,64 @@ class MemberViewSet(viewsets.ModelViewSet):
'female': serializer.validated_data.get('female', False),
}
if not email or email.startswith('dummy_'):
# 直接登録
if email:
user, created = CustomUser.objects.get_or_create(
email=email,
defaults={**user_data, 'is_active':True}
)
# 自分自身を登録する場合
if request.user.email == email:
member, created = Member.objects.get_or_create(user=request.user, team=team)
if created:
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
else:
# emailが空の場合、一意のダミーメールアドレスを生成
dummy_email = f"dummy_{uuid.uuid4()}@example.com"
user = CustomUser.objects.create(email=dummy_email, **user_data)
return Response({"message": "You are already a member of this team."}, status=status.HTTP_200_OK)
member = Member.objects.create(user=user, team=team)
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
if not email or email.startswith('dummy_'):
logger.info("Processing as direct registration")
# 直接登録
try:
if email:
user, created = CustomUser.objects.get_or_create(
email=email,
defaults={**user_data, 'is_active':True}
)
else:
# emailが空の場合、一意のダミーメールアドレスを生成
dummy_email = f"dummy_{uuid.uuid4()}@example.com"
user = CustomUser.objects.create(email=dummy_email, **user_data)
member = Member.objects.create(user=user, team=team)
logger.info(f"Member created successfully: {member.id}")
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
except Exception as e:
logger.error(f"Error creating member: {str(e)}")
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
#member = serializer.save(team=team)
#return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
logger.info("Processing as temporary registration")
# 仮登録
existing_user = CustomUser.objects.filter(email=email).first()
if existing_user:
logger.info(f"Existing user found: {existing_user.id}")
# 既存ユーザーの場合、チーム招待メールを送信
send_team_join_email(existing_user, team)
send_team_join_email(request.user,existing_user, team)
return Response({"message": "Invitation for your team sent to existing user."}, status=status.HTTP_200_OK)
else:
print("新規ユーザー")
temp_user = TempUser.objects.create(
email=email,
**user_data,
verification_code=str(uuid.uuid4())
)
send_invitation_email(temp_user, team) #仮登録済みでも確認メールを送る。
logger.info("Inviting new temporary user")
return Response({"message": "Invitation email sent to the user."}, status=status.HTTP_201_CREATED)
try:
print("新規ユーザー")
#temp_user = TempUser.objects.create(
# email=email,
# **user_data,
# verification_code=str(uuid.uuid4())
#)
send_invitation_email(request.user,request,email, team) #仮登録済みでも確認メールを送る。
logger.info(f"Invitation email sent to: {email}")
return Response({"message": "Invitation email sent to the user."}, status=status.HTTP_201_CREATED)
except Exception as e:
logger.info(f"Error on Invitation email sent to: {email} : {e}")
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
'''
@ -1252,6 +1378,59 @@ class MemberViewSet(viewsets.ModelViewSet):
self.check_object_permissions(self.request, obj)
return obj
class ActivateMemberView(APIView):
def get(self, request, user_id, team_id):
user = get_object_or_404(CustomUser, id=user_id)
team = get_object_or_404(Team, id=team_id)
# メンバーオブジェクトを取得または作成
member, created = Member.objects.get_or_create(user=user, team=team)
if member.lastname == "dummy":
# userデータでmemberデータを更新
member.lastname = user.lastname
member.firstname = user.firstname
member.date_of_birth = user.date_of_birth
member.female = user.female
member.save()
message = f"{team.team_name}に正常に参加し、メンバー情報が更新されました。アプリのチーム管理で確認できます。"
else:
message = f"{team.team_name}に正常に参加しました。"
return render(request, 'activation_success.html', {'message': message})
class ActivateNewMemberView(APIView):
def get(self, request, verification_code, team_id):
try:
team = Team.objects.get(id=team_id)
member, created = Member.objects.get_or_create(team=team, user__email=email)
if created:
return Response({'message': 'Member activated successfully'}, status=status.HTTP_201_CREATED)
else:
return Response({'message': 'Member already exists'}, status=status.HTTP_200_OK)
except Team.DoesNotExist:
return Response({'message': 'Invalid team'}, status=status.HTTP_400_BAD_REQUEST)
'''
temp_user = get_object_or_404(TempUser, verification_code=verification_code)
team = get_object_or_404(Team, id=team_id)
user = CustomUser.objects.create_user(
email=temp_user.email,
password=temp_user.password, # Ensure this is securely handled
**{k: v for k, v in temp_user.__dict__.items() if k in ['firstname', 'lastname', 'date_of_birth', 'female']}
)
Member.objects.create(user=user, team=team)
temp_user.delete()
message = f"アカウントが作成され、{team.team_name}に参加しました。アプリのチーム管理で確認できます。"
return render(request, 'activation_success.html', {'message': message})
'''
class OwnerEntriesView(generics.ListAPIView):
serializer_class = EntrySerializer
permission_classes = [permissions.IsAuthenticated]
@ -1461,13 +1640,24 @@ class VerifyEmailView(APIView):
password=temp_user.password,
**{k: v for k, v in user_data.items() if k != 'email'}
)
temp_user.delete()
return Response({'message': 'Email verified and user created'}, status=status.HTTP_201_CREATED)
# チームへの追加処理(もし必要なら)
if hasattr(temp_user, 'team_id'):
team = Team.objects.get(id=temp_user.team_id)
Member.objects.create(user=user, team=team)
message = f"メールアドレスが確認され、アカウントが作成されました。{team.team_name}のメンバーとして登録されています。アプリでログインして、必要な情報を入力してください。"
else:
message = "メールアドレスが確認され、アカウントが作成されました。アプリでログインして、必要な情報を入力してください。"
temp_user.delete()
return render(request, 'verification_success.html', {'message': message})
else:
return Response({'message': 'Verification link expired'}, status=status.HTTP_400_BAD_REQUEST)
message = "確認リンクの有効期限が切れています。アプリから認証コードの再送信をしてください。"
return render(request, 'verification_success.html', {'message': message})
except TempUser.DoesNotExist:
return Response({'message': 'Invalid verification code'}, status=status.HTTP_400_BAD_REQUEST)
message = "無効な確認コードです。"
return render(request, 'verification_success.html', {'message': message})
class MemberUserDetailView(generics.RetrieveAPIView):