Basic release 1-Aug-2024
This commit is contained in:
330
rog/views.py
330
rog/views.py
@ -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):
|
||||
|
||||
Reference in New Issue
Block a user