import requests from rest_framework import serializers from django.db import IntegrityError from django.urls import reverse from .utils import send_verification_email,send_invitation_email,send_team_join_email from django.conf import settings import uuid from rest_framework.exceptions import ValidationError as DRFValidationError from django.db import transaction from django.db.models import F from rest_framework import viewsets, permissions, status from rest_framework.decorators import action from rest_framework.response import Response from django.shortcuts import get_object_or_404 from .models import Team, Member, CustomUser, NewCategory from .serializers import TeamSerializer, MemberSerializer, CustomUserSerializer, TeamDetailSerializer,UserUpdateSerializer,UserRegistrationSerializer from .permissions import IsTeamOwner from curses.ascii import NUL from django.core.serializers import serialize from .models import GoalImages, Location, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, GifuAreas, RogUser, CustomUser, UserTracks, GoalImages, CheckinImages, NewEvent,NewEvent2, Team, Category, NewCategory,Entry, Member, TempUser,EntryMember from rest_framework import viewsets from .serializers import LocationSerializer, Location_lineSerializer, Location_polygonSerializer, JPN_main_perfSerializer, LocationCatSerializer, UserSerializer, LoginUserSerializer, UseractionsSerializer, UserDestinationSerializer, GifuAreaSerializer, LocationEventNameSerializer, RogUserSerializer, UserTracksSerializer, ChangePasswordSerializer, GolaImageSerializer, CheckinImageSerializer, RegistrationSerializer, MemberWithUserSerializer,TempUserRegistrationSerializer from knox.models import AuthToken from rest_framework import viewsets, generics, status from rest_framework.response import Response from rest_framework.parsers import JSONParser, MultiPartParser from .serializers import LocationSerializer from django.http import JsonResponse from rest_framework.permissions import IsAuthenticated from django.contrib.gis.db.models import Extent, Union from .serializers import TestSerialiser,NewEventSerializer,NewEvent2Serializer, TeamSerializer, NewCategorySerializer,CategorySerializer, EntrySerializer, MemberSerializer, TempUserSerializer, CustomUserSerializer,EntryMemberSerializer,MemberCreationSerializer,EntryCreationSerializer from .models import TestModel from django.shortcuts import get_object_or_404 from django.db.models import F from django.contrib.gis import geos from django.db.models import Q from rest_framework import permissions from rest_framework.views import APIView from rest_framework.decorators import api_view from rest_framework.decorators import api_view, permission_classes from rest_framework.parsers import JSONParser, MultiPartParser from django.views.decorators.csrf import csrf_exempt from django.shortcuts import render from .permissions import IsMemberOrTeamOwner from django.utils.decorators import method_decorator from django.utils.encoding import force_str import logging from datetime import datetime from django.utils.dateparse import parse_date logger = logging.getLogger(__name__) class LocationViewSet(viewsets.ModelViewSet): queryset=Location.objects.all() serializer_class=LocationSerializer filter_fields=["prefecture", "location_name"] class Location_lineViewSet(viewsets.ModelViewSet): queryset=Location_line.objects.all() serializer_class=Location_lineSerializer class Location_polygonViewSet(viewsets.ModelViewSet): queryset=Location_polygon.objects.all() serializer_class=Location_polygonSerializer class Jpn_Main_PerfViewSet(viewsets.ModelViewSet): queryset=JpnAdminMainPerf.objects.filter(id=9) serializer_class=JPN_main_perfSerializer filter_fields = ["adm1_ja"] class UserTracksViewSet(viewsets.ModelViewSet): queryset = UserTracks.objects.all() serializer_class = UserTracksSerializer @api_view(['PUT']) @permission_classes([IsAuthenticated]) def update_user_info(request, user_id): try: user = CustomUser.objects.get(id=user_id) except CustomUser.DoesNotExist: return Response({"error": "User not found"}, status=status.HTTP_404_NOT_FOUND) if request.user.id != user_id: return Response({"error": "You don't have permission to update this user's information"}, status=status.HTTP_403_FORBIDDEN) data = request.data logger.debug(f"Received data for update: {data}") # CustomUserの更新可能なフィールドを指定 updateable_fields = ['zekken_number', 'event_code', 'team_name', 'group'] #for field in updateable_fields: # if field in data: # setattr(user, field, data[field]) updated_fields = [] for field in updateable_fields: if field in data: old_value = getattr(user, field) setattr(user, field, data[field]) new_value = getattr(user, field) if old_value != new_value: updated_fields.append(f"{field}: {old_value} -> {new_value}") logger.debug(f"Fields to be updated: {updated_fields}") try: user.save() logger.info(f"User {user_id} updated. Changed fields: {', '.join(updated_fields)}") serializer = CustomUserSerializer(user) return Response(serializer.data, status=status.HTTP_200_OK) except Exception as e: logger.error(f"Error updating user {user_id}: {str(e)}") return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) @api_view(['PUT']) @permission_classes([IsAuthenticated]) def update_user_detail(request, user_id): try: user = CustomUser.objects.get(id=user_id) except CustomUser.DoesNotExist: return Response({"error": "User not found"}, status=status.HTTP_404_NOT_FOUND) if request.user.id != user_id: return Response({"error": "You don't have permission to update this user's information"}, status=status.HTTP_403_FORBIDDEN) data = request.data logger.debug(f"Received data for update: {data}") # CustomUserの更新可能なフィールドを指定 updateable_fields = ['firstname', 'lastname', 'date_of_birth', 'female'] #for field in updateable_fields: # if field in data: # setattr(user, field, data[field]) updated_fields = [] for field in updateable_fields: if field in data: old_value = getattr(user, field) 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}") try: user.save() 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) except Exception as e: logger.error(f"Error updating user {user_id}: {str(e)}") return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) def LocationsInPerf(request): perfecture = request.GET.get('perf') is_rog = request.GET.get('rog') cat = request.GET.get('cat') grp = request.GET.get('grp') perf_geom = JpnAdminMainPerf.objects.get(id=perfecture) if(cat): if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom, category=cat, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom, category=cat) else: if grp: locs = Location.objects.filter(geom__within=perf_geom.geom, category=cat, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(geom__within=perf_geom.geom, category=cat, location_name__contains='観光') else: if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom) else: if grp: locs = Location.objects.filter(geom__within=perf_geom.geom, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(geom__within=perf_geom.geom, location_name__contains='観光') serializer = LocationSerializer(locs, many=True) return JsonResponse(serializer.data, safe=False) def LocationsInSubPerf(request): subperfecture = request.GET.get('subperf') is_rog = request.GET.get('rog') cat = request.GET.get('cat') grp = request.GET.get('grp') perf_geom = JpnSubPerf.objects.get(id=subperfecture) if(cat): if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom, category=cat, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom, category=cat) else: if grp: locs = Location.objects.filter(geom__within=perf_geom.geom, category=cat, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(geom__within=perf_geom.geom, category=cat, location_name__contains='観光') else: if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), geom__within=perf_geom.geom) else: locs = Location.objects.filter(geom__within=perf_geom.geom, location_name__contains='観光') serializer = LocationSerializer(locs, many=True) return JsonResponse(serializer.data, safe=False) # この関数LocationInBoundは、地理的な範囲内にある特定の条件を満たす位置情報を検索し、結果をJSON形式で返すものです。主なロジックは以下の通りです: # # 1.リクエストパラメータの取得: # 4つの緯度経度ペア(lat1/lon1からlat4/lon4) # カテゴリ(cat) # グループ(grp) # ROG(Region of Gaze)フラグ(is_rog) # # 2. 境界ポリゴンの作成: # 4つの緯度経度ペアが全て提供された場合、それらを使用してジオメトリポリゴンを作成します。 # # 3.位置情報のフィルタリング: # 基本的に、ポリゴン内(geom__within=pl)にある位置情報を検索します。 # イベント名がない(event_name__isnull=True)位置情報のみを対象とします。 # カテゴリ、グループ、ROGフラグの有無に応じて、さらにフィルタリングを行います: # カテゴリが指定された場合、そのカテゴリに一致する位置情報のみを検索します。 # ROGフラグがある場合、cp(おそらくcheck point)が0でない位置情報を検索します。 # ROGフラグがない場合、location_nameに'観光'を含む位置情報のみを検索します。 # グループが指定された場合、そのグループを含む位置情報のみを検索します。 # # 4.結果の返却: # 検索結果が120件を超える場合、"too_many_points"フラグを立てたJSONレスポンスを返します。 # それ以外の場合、LocationSerializerを使用して位置情報をシリアライズし、JSONレスポンスとして返します。 # # 5.エラーハンドリング: # 必要な緯度経度パラメータが不足している場合、空のJSONオブジェクトを返します。 # # この関数は、主に観光関連の位置情報を特定の地理的範囲内で検索し、様々な条件でフィルタリングすることができます。ROGフラグの有無によって検索条件が変わるのが特徴的です。 # def LocationInBound(request): logger.debug(f"Received request parameters: {request.GET}") lat1 = float(request.GET.get('la1')) lon1 = float(request.GET.get('ln1')) lat2 = float(request.GET.get('la2')) lon2 = float(request.GET.get('ln2')) lat3 = float(request.GET.get('la3')) lon3 = float(request.GET.get('ln3')) lat4 = float(request.GET.get('la4')) lon4 = float(request.GET.get('ln4')) cat = request.GET.get('cat') grp = request.GET.get('grp') is_rog = request.GET.get('rog') logger.debug(f"Parsed parameters: lat1={lat1}, lon1={lon1}, lat2={lat2}, lon2={lon2}, " f"lat3={lat3}, lon3={lon3}, lat4={lat4}, lon4={lon4}, " f"cat={cat}, grp={grp}, is_rog={is_rog}") if(lat1 != None and lon1 != None and lat2 != None and lon2 != None and lat3 != None and lon3 != None and lat4 != None and lon4 != None): pl = geos.Polygon(((lon1, lat1), (lon2, lat2), (lon3, lat3), (lon4, lat4), (lon1, lat1)), srid=4326) logger.debug(f"Created polygon: {pl}") base_query = Location.objects.filter(geom__within=pl, event_name__isnull=True) if cat: base_query = base_query.filter(category=cat) if is_rog: base_query = base_query.filter(~Q(cp=0)) else: base_query = base_query.filter(location_name__contains='観光') if grp: base_query = base_query.filter(group__contains=grp) logger.debug(f"Final query: {base_query.query}") locs = base_query logger.debug(f"Number of locations found: {len(locs)}") ''' if(cat): if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), geom__within=pl, category=cat, event_name__isnull=True, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), geom__within=pl, category=cat, event_name__isnull=True) else: if grp: locs = Location.objects.filter(geom__within=pl, category=cat, event_name__isnull=True, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(geom__within=pl, category=cat, event_name__isnull=True, location_name__contains='観光') else: if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), geom__within=pl, event_name__isnull=True, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), geom__within=pl, event_name__isnull=True) else: if grp: locs = Location.objects.filter(geom__within=pl, event_name__isnull=True, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(geom__within=pl, event_name__isnull=True, location_name__contains='観光') ''' if len(locs) > 200: return JsonResponse({"too_many_points": True}, safe=False, status=500) else: serializer = LocationSerializer(locs, many=True) return JsonResponse(serializer.data, safe=False) else: return JsonResponse({}, safe=False) def SubInPerf(request): prefecture = request.GET.get('perf') perf_geom = JpnAdminMainPerf.objects.get(id=prefecture) sub = JpnAdminPerf.objects.filter(geom__within=perf_geom.geom) serializer = JPN_perfSerializer(sub, many=True) return JsonResponse(serializer.data, safe=False) def SubPerfInMainPerf(request): area = request.GET.get('area') perf_geom = GifuAreas.objects.get(id=area) sub = JpnSubPerf.objects.filter(geom__contained=perf_geom.geom) #serializer = JPN_sub_perSerializer #sub = JpnAdminPerf.objects.filter(geom__within=perf_geom.geom) serializer = JPN_sub_perSerializer(sub, many=True) return JsonResponse(serializer.data, safe=False) def GetAllGifuAreas(request): prefecture = request.GET.get('perf') perf_geom = JpnAdminMainPerf.objects.get(id=prefecture) sub = GifuAreas.objects.filter(geom__contained=perf_geom.geom) serializer = GifuAreaSerializer(sub, many=True) return JsonResponse(serializer.data, safe=False) def ExtentForMainPerf(request): perf_id = request.GET.get('perf') perf = JpnAdminMainPerf.objects.get(id=perf_id) ext = perf.geom.extent # iata = serializers.serialize("json",ext) return JsonResponse(ext, safe=False) @api_view(['POST',]) @permission_classes((IsAuthenticated,)) @csrf_exempt def ExtentForLocations(request): user = request.user ec = user.event_code #print(user.event_code) locs = Location.objects.filter(group__contains=ec).aggregate(Extent('geom'), Union('geom')) return JsonResponse(locs['geom__extent'], safe=False) def ExtentForSubPerf(request): sub_perf_id = request.GET.get('sub_perf') sub_perf = JpnSubPerf.objects.get(id=sub_perf_id) ext = sub_perf.geom.extent # iata = serializers.serialize("json",ext) return JsonResponse(ext, safe=False) def CatView(request): lat1 = float(request.GET.get('la1')) lon1 = float(request.GET.get('ln1')) lat2 = float(request.GET.get('la2')) lon2 = float(request.GET.get('ln2')) lat3 = float(request.GET.get('la3')) lon3 = float(request.GET.get('ln3')) lat4 = float(request.GET.get('la4')) lon4 = float(request.GET.get('ln4')) if(lat1 != None and lon1 != None and lat2 != None and lon2 != None and lat3 != None and lon3 != None and lat4 != None and lon4 != None): pl = geos.Polygon(((lon1, lat1), (lon2, lat2), (lon3, lat3), (lon4, lat4), (lon1, lat1)), srid=4326) #locs = Location.objects.filter(geom__within=pl) c = Location.objects.filter(geom__within=pl).values('category').distinct() serializer = LocationCatSerializer(c, many=True) return JsonResponse(serializer.data, safe=False) else: return null c = Location.objects.filter().values('category').distinct() serializer = LocationCatSerializer(c, many=True) return JsonResponse(serializer.data, safe=False) def CatByCity(request): city = request.GET.get('city') if(city != None): cilt_polygon = JpnSubPerf.objects.filter(adm1_ja=city) cats = Location.objects.filter(geom__within=cilt_polygon[0].geom).values('category').distinct() serializer = LocationCatSerializer(cats, many=True) return JsonResponse(serializer.data, safe=False) else: return None class RegistrationAPI(generics.GenericAPIView): #serializer_class = CreateUserSerializer serializer_class = UserRegistrationSerializer def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.save() return Response({ "user": UserSerializer(user, context=self.get_serializer_context()).data, "token": AuthToken.objects.create(user)[1] }) class LoginAPI(generics.GenericAPIView): serializer_class = LoginUserSerializer def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.validated_data return Response({ "user": UserSerializer(user, context=self.get_serializer_context()).data, "token": AuthToken.objects.create(user)[1] }) class UserUpdateAPI(generics.UpdateAPIView): permission_classes = [permissions.IsAuthenticated] serializer_class = UserUpdateSerializer def get_object(self): return self.request.user def update(self, 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) # User 情報取得 class UserAPI(generics.RetrieveAPIView): permission_classes = [permissions.IsAuthenticated,] serializer_class = UserSerializer def get_object(self): return self.request.user # @api_view(['POST',]) # @permission_classes((IsAuthenticated,)) # @csrf_exempt # class GoalImageViewSet(APIView): # permissions_classes = [permissions.IsAuthenticated,] # # parser_classes = [MultiPartParser, JSONParser] # def post(self, request, format=None): # # print(request.data) # serializer = GolaImageSerializer(data=request.data) # if serializer.is_valid(): # serializer.save() # return Response(serializer.data, status=status.HttP_200_OK) # else: # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # return Response({"ok":"ok"}) class GoalImageViewSet(viewsets.ModelViewSet): queryset=GoalImages.objects.all() serializer_class=GolaImageSerializer # parser_classes = (MultiPartParser, JSONParser) def get_queryset(self): queryset = GoalImages.objects.all() # dist = self.request.GET.get('dist') # if dist != None : # queryset = Incident.objects.filter(entity=dist, is_approved=True) # else: # queryset = Incident.objects.filter(is_approved=True) return queryset class CheckinImageViewSet(viewsets.ModelViewSet): queryset=CheckinImages.objects.all() serializer_class=CheckinImageSerializer # parser_classes = (MultiPartParser, JSONParser) def get_queryset(self): queryset = CheckinImages.objects.all() # dist = self.request.GET.get('dist') # if dist != None : # queryset = Incident.objects.filter(entity=dist, is_approved=True) # else: # queryset = Incident.objects.filter(is_approved=True) return queryset class RetrieveUserView(generics.RetrieveAPIView): queryset = CustomUser.objects.all() serializer_class = UserSerializer permission_classes = [IsAuthenticated] def get_object(self): return self.request.user def userDetials(request): user_id = request.GET.get('user_id') user = CustomUser.objects.get(id=user_id) rogUser = RogUser.objects.filter(user=user) serializer = RogUserSerializer(rogUser, many=True) return JsonResponse(serializer.data, safe=False) @api_view(['GET']) @permission_classes((IsAuthenticated, )) def DeleteAccount(request): usr = request.user; #print("user is" + usr) if(usr): #usr.delete() usr.email = usr.email + "_res" + str(uuid.uuid4()) usr.save(); AuthToken.objects.filter(user=usr).delete() return Response({"result":"user deleted"}) return Response({"result":"user not found"}) ''' def send_verification_email(self, temp_user): subject = '仮登録の確認' message = f'以下のリンクをクリックして登録を完了してください:\n{settings.FRONTEND_URL}/verify/{temp_user.verification_code}' from_email = settings.DEFAULT_FROM_EMAIL recipient_list = [temp_user.email] try: send_mail(subject, message, from_email, recipient_list) logger.info(f"Verification email sent to {temp_user.email}") except Exception as e: logger.error(f"Failed to send verification email to {temp_user.email}. Error: {str(e)}") ''' def UserActionViewset(request): user_id = request.GET.get('user_id') location_id = request.GET.get('location_id') location = Location.objects.get(location_id=location_id) user = CustomUser.objects.get(id=user_id) action = Useractions.objects.filter(location=location, user=user) serializer = UseractionsSerializer(action, many=True) return JsonResponse(serializer.data, safe=False) def UserMakeActionViewset(request): user_id = request.GET.get('user_id') location_id = request.GET.get('location_id') wanttogo = True if request.GET.get('wanttogo') == "true" else False like = True if request.GET.get('like') == "true" else False checkin = True if request.GET.get('checkin') == "true" else False location = Location.objects.get(location_id=location_id) user = CustomUser.objects.get(id=user_id) #action = Useractions.objects.filter(location__id=location_id, user__id=user_id) rec = Useractions.objects.filter(user=user, location=location) if(rec): obj = rec.update(wanttogo=wanttogo, like=like, checkin=checkin) else: obj, created = Useractions.objects.update_or_create(user=user, location=location, wanttogo=wanttogo, like=like, checkin=checkin) serializer = UseractionsSerializer(obj, many=False) return JsonResponse(serializer.data, safe=False) def UserDestinations(request): user_id = request.GET.get('user_id') user = CustomUser.objects.get(id=user_id) #action = Useractions.objects.filter(location__id=location_id, user__id=user_id) rec = Useractions.objects.filter(user=user, wanttogo=True).order_by('order') serializer = UserDestinationSerializer(rec, many=True) return JsonResponse(serializer.data, safe=False) def UpdateOrder(request): dir = request.GET.get('dir') user_action_id = int(request.GET.get('user_action_id')) order = int(request.GET.get('order')) aorder = int(request.GET.get('order')) oorder = int(request.GET.get('order')) if(user_action_id): #updated = Useractions.objects.filter(order__gte=order).update(order = F('order')+1) #res = Useractions.objects.filter(id=user_action_id).update(order=order) index = 0 if dir == "up": for id in Useractions.objects.all().order_by('order').values_list('id', flat=True): print(id) print("----",user_action_id) if index == order : index += 1 print("index increated .....") if user_action_id == id: Useractions.objects.filter(id=id).update(order=order) print("updated .....") continue Useractions.objects.filter(id=id).update(order=index) index += 1 else : for id in Useractions.objects.all().order_by('order').values_list('id', flat=True): print(id) print("----",user_action_id) if index == order : index -= 1 print("index increated .....") if user_action_id == id: Useractions.objects.filter(id=id).update(order=order) print("updated .....") continue Useractions.objects.filter(id=id).update(order=index) index += 1 # for id in Useractions.objects.values_list('order', flat=True): # aorder -= 1 # Useractions.objects.filter(order__lt=id).update(order=aorder) # res = Useractions.objects.filter(id=user_action_id).update(order=oorder) return JsonResponse(1, safe=False) else: return JsonResponse({}, safe=False) def DeleteDestination(request): dest_id = int(request.GET.get('dest_id')) print("###### dest ") print(dest_id) if(dest_id != None): Useractions.objects.filter(id=dest_id).delete() return JsonResponse({"success":1}, safe=False) else: return JsonResponse({"success":0}, safe=False) def CustomAreaLocations(request): cat = request.GET.get('cat') name = request.GET.get('name') is_rog = request.GET.get('rog') grp = request.GET.get('grp') if(cat != None): if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), event_name__isnull=False, category=cat, event_name=name, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), event_name__isnull=False, category=cat, event_name=name) else: if grp: locs = Location.objects.filter(event_name__isnull=False, category=cat, event_name=name, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(event_name__isnull=False, category=cat, event_name=name, location_name__contains='観光') else: if is_rog: if grp: locs = Location.objects.filter(~Q(cp=0), event_name__isnull=False, event_name=name, group__contains=grp) else: locs = Location.objects.filter(~Q(cp=0), event_name__isnull=False, event_name=name) else: if grp: locs = Location.objects.filter(event_name__isnull=False, event_name=name, group__contains=grp, location_name__contains='観光') else: locs = Location.objects.filter(event_name__isnull=False, event_name=name, location_name__contains='観光') serializer = LocationSerializer(locs, many=True) return JsonResponse(serializer.data, safe=False) def CustomAreaNames(request): locs = Location.objects.filter(event_name__isnull=False).values('event_name').distinct() serializer = LocationEventNameSerializer(locs, many=True) return JsonResponse(serializer.data, safe=False) class UserActivationView(APIView): def get(self, request, activation_token): try: temp_user = TempUser.objects.get(verification_code=activation_token) user = CustomUser.objects.create( email=temp_user.email, firstname=temp_user.firstname, lastname=temp_user.lastname, date_of_birth=temp_user.date_of_birth, female=temp_user.female, is_active=True ) # Here you might want to add the user to the team they were invited to temp_user.delete() return Response({"message": "アカウントが正常にアクティベートされました。"}, status=status.HTTP_200_OK) except TempUser.DoesNotExist: return Response({"error": "無効なアクティベーショントークンです。"}, status=status.HTTP_400_BAD_REQUEST) ''' def get(self, request, activation_token): try: user = CustomUser.objects.get(activation_token=activation_token, is_active=False) user.is_active = True user.activation_token = None user.save() return Response({"message": "アカウントが正常にアクティベートされました。"}, status=status.HTTP_200_OK) except CustomUser.DoesNotExist: return Response({"error": "無効なアクティベーショントークンです。"}, status=status.HTTP_400_BAD_REQUEST) ''' class ChangePasswordView(generics.UpdateAPIView): """ An endpoint for changing password. """ serializer_class = ChangePasswordSerializer model = CustomUser permission_classes = (IsAuthenticated,) def get_object(self, queryset=None): obj = self.request.user return obj def update(self, request, *args, **kwargs): self.object = self.get_object() serializer = self.get_serializer(data=request.data) if serializer.is_valid(): # Check old password if not self.object.check_password(serializer.data.get("old_password")): return Response({"old_password": ["Wrong password."]}, status=status.HTTP_400_BAD_REQUEST) # set_password also hashes the password that the user will get self.object.set_password(serializer.data.get("new_password")) self.object.save() response = { 'status': 'success', 'code': status.HTTP_200_OK, 'message': 'Password updated successfully', 'data': [] } return Response(response) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class TestActionViewSet(viewsets.ModelViewSet): serializer_class = TestSerialiser queryset = TestModel.objects.all() def PrivacyView(request): return render(request, "rog/privacy.html") class RegistrationView(APIView): @transaction.atomic def post(self, request): serializer = UserRegistrationSerializer(data=request.data) if serializer.is_valid(): try: user = serializer.save() logger.info(f"New user registered: {user.email}") return Response({"message": "ユーザー登録が完了しました。"}, status=status.HTTP_201_CREATED) except Exception as e: logger.error(f"Error during user registration: {str(e)}") return Response({"error": "ユーザー登録中にエラーが発生しました。"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) else: logger.warning(f"Invalid registration data: {serializer.errors}") return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # Akira class NewEvent2ViewSet(viewsets.ModelViewSet): queryset = NewEvent2.objects.all() serializer_class = NewEvent2Serializer permission_classes = [IsAuthenticated] class NewEvent2ListView(generics.ListAPIView): queryset = NewEvent2.objects.all() serializer_class = NewEvent2Serializer permission_classes = [IsAuthenticated] class NewEventViewSet(viewsets.ModelViewSet): queryset = NewEvent.objects.all() serializer_class = NewEventSerializer permission_classes = [IsAuthenticated] class NewEventListView(generics.ListAPIView): queryset = NewEvent.objects.all() serializer_class = NewEventSerializer permission_classes = [IsAuthenticated] class TeamViewSet(viewsets.ModelViewSet): serializer_class = TeamSerializer permission_classes = [permissions.IsAuthenticated, IsTeamOwner] def get_queryset(self): 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'] category = NewCategory.objects.select_for_update().get(id=category.id) zekken_number = category.category_number category.category_number = F('category_number') + 1 category.save() category.refresh_from_db() # F() 式の結果を評価 team = serializer.save(owner=self.request.user, zekken_number=zekken_number) logger.info(f"Team created successfully: {team.id}") # 外部システムの更新 success = self.register_team( team.owner, team.zekken_number, team.owner.event_code, team.team_name, team.category.category_name, 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": "チームにメンバーが残っているため削除できません。", "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: 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() # 外部システムの更新 success = update_external_system( team.zekken_number, team.owner.event_code, team.team_name, team.category.category_name, team.owner.password ) if not success: raise serializers.ValidationError("外部システムの更新に失敗しました。") else: print("岐阜ロゲシステム更新に成功") @action(detail=True, methods=['post']) def copy(self, request, pk=None): original_team = self.get_object() with transaction.atomic(): category = NewCategory.objects.select_for_update().get(id=original_team.category.id) new_zekken_number = category.category_number category.category_number = F('category_number') + 1 category.save() category.refresh_from_db() # F() 式の結果を評価 new_team = Team.objects.create( zekken_number=new_zekken_number, team_name=f"{original_team.team_name} (コピー)", category=category, owner=request.user ) for member in original_team.members.all(): Member.objects.create( team=new_team, user=member.user ) return Response(TeamSerializer(new_team).data, status=status.HTTP_201_CREATED) class NewCategoryViewSet(viewsets.ModelViewSet): queryset = NewCategory.objects.all() serializer_class = NewCategorySerializer permission_classes = [IsAuthenticated] class NewCategoryListView(generics.ListAPIView): queryset = NewCategory.objects.all() serializer_class = NewCategorySerializer permission_classes = [IsAuthenticated] class CategoryViewSet(viewsets.ModelViewSet): queryset = Category.objects.all() serializer_class = CategorySerializer permission_classes = [IsAuthenticated] class CategoryListView(generics.ListAPIView): queryset = Category.objects.all() serializer_class = CategorySerializer permission_classes = [IsAuthenticated] ''' def get(self, request): categories = Category.objects.all() data = [] for category in categories: category_name = force_str(category.category_name) data.append({ 'category_name': category_name, # その他のフィールド }) return Response(data) ''' class EntryViewSet(viewsets.ModelViewSet): #queryset = Entry.objects.all() serializer_class = EntrySerializer permission_classes = [permissions.IsAuthenticated] #def perform_create(self, serializer): # team = Team.objects.get(owner=self.request.user) # serializer.save(team=team) def get_queryset(self): user = self.request.user # ユーザーが所有するチームのIDを取得 owned_team_ids = Team.objects.filter(owner=user).values_list('id', flat=True) # ユーザーがメンバーとして所属するチームのIDを取得 member_team_ids = Member.objects.filter(user=user).values_list('team_id', flat=True) # 両方のチームに関連するエントリーを取得 return Entry.objects.filter(Q(team__id__in=owned_team_ids) | Q(team__id__in=member_team_ids)) def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) try: serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) except DRFValidationError as e: return Response({'error': self.format_errors(e.detail)}, status=status.HTTP_400_BAD_REQUEST) # except IntegrityError: # return Response({'error': '既に登録済みです'}, status=status.HTTP_400_BAD_REQUEST) except IntegrityError as e: return Response({'error': f'データベースエラー: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST) except Exception as e: return Response({'error': f"予期せぬエラーが発生しました: {str(e),'type': str(type(e))}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) def perform_create(self, serializer): serializer.save(owner=self.request.user) def update(self, request, *args, **kwargs): logger.info(f"Update method called for Entry with ID: {kwargs.get('pk')}") logger.debug(f"Request data: {request.data}") partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) try: serializer.is_valid(raise_exception=True) logger.debug(f"Serializer validated data: {serializer.validated_data}") except serializers.ValidationError as e: logger.error(f"Validation error: {e.detail}") return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) try: self.perform_update(serializer) logger.info(f"Entry updated successfully: {serializer.data}") except Exception as e: logger.exception(f"Error updating Entry: {str(e)}") return Response({"error": "An error occurred while updating the entry."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response(serializer.data) def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) def get_error_message(self, exception): if hasattr(exception, 'detail'): if isinstance(exception.detail, dict): return '. '.join([f"{key}: {', '.join(value)}" for key, value in exception.detail.items()]) elif isinstance(exception.detail, list): return '. '.join(exception.detail) return str(exception) def format_errors(self, errors): if isinstance(errors, list): return '. '.join(errors) elif isinstance(errors, dict): return '. '.join([f"{key}: {value}" if isinstance(value, str) else f"{key}: {', '.join(value)}" for key, value in errors.items()]) else: return str(errors) class MemberViewSet(viewsets.ModelViewSet): serializer_class = MemberSerializer permission_classes = [permissions.IsAuthenticated,IsTeamOwner] def get_serializer_class(self): if self.action == 'create': return MemberCreationSerializer return MemberSerializer def get_queryset(self): 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 = 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', ''), 'lastname': serializer.validated_data.get('lastname', ''), 'date_of_birth': serializer.validated_data.get('date_of_birth'), 'female': serializer.validated_data.get('female', False), } # 自分自身を登録する場合 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: return Response({"message": "You are already a member of this team."}, status=status.HTTP_200_OK) 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(request.user,existing_user, team) return Response({"message": "Invitation for your team sent to existing user."}, status=status.HTTP_200_OK) else: logger.info("Inviting new temporary user") 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) ''' def create(self, request, *args, **kwargs): team = Team.objects.get(id=self.kwargs['team_id']) serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) try: self.perform_create(serializer) except DRFValidationError as e: return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) #except ValidationError as e: # return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) except IntegrityError: return Response({"error": "このユーザーは既にチームのメンバーです。"}, status=status.HTTP_400_BAD_REQUEST) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) ''' ''' def send_activation_email(self, temp_user, team): # アクティベーションメール送信のロジックをここに実装 # 注意: 'user-activation' URLパターンが存在しない場合は、適切なURLを生成する方法を検討する必要があります activation_url = "dummy url" #f"{settings.FRONTEND_URL}/activate/{temp_user.verification_code}" # ここでemailを送信するロジックを実装 print(f"Activation email would be sent to {temp_user.email} with URL: {activation_url}") def send_invitation_email(self, user, team): # チーム招待メール送信のロジック #invitation_url = self.request.build_absolute_uri( # reverse('team-invite', kwargs={'team_id': team.id, 'user_id': user.id}) #) #subject = f"Invitation to join {team.name}" #message = f"You have been invited to join the team {team.name}. Click here to accept: {invitation_url}" #from_email = settings.DEFAULT_FROM_EMAIL #recipient_list = [user.email] #send_mail(subject, message, from_email, recipient_list) # チーム招待メール送信のロジックをここに実装 # 注意: 'team-invitation' URLパターンが存在しない場合は、適切なURLを生成する方法を検討する必要があります # 例えば、フロントエンドのURLを直接指定する方法など invitation_url = "dummy url" #f"{settings.FRONTEND_URL}/team/{team.id}/invite" # ここでemailを送信するロジックを実装 print(f"Invitation email would be sent to {user.email} with URL: {invitation_url}") ''' def perform_create(self, serializer): team = Team.objects.get(id=self.kwargs['team_id']) serializer.save(team=team) @transaction.atomic def update(self, request, *args, **kwargs): #partial = kwargs.pop('partial', False) instance = self.get_object() user = instance.user logger.debug(f"Updating user: {user.email}") logger.debug(f"Received data: {request.data}") if user.email.startswith('dummy_'): logger.debug("User has dummy email, proceeding with update") # 直接データを更新 user.firstname = request.data.get('firstname', user.firstname) user.lastname = request.data.get('lastname', user.lastname) # 日付の処理 date_of_birth = request.data.get('date_of_birth') if date_of_birth: try: date_of_birth = date_of_birth.translate(str.maketrans("0123456789", "0123456789")) parsed_date = parse_date(date_of_birth) if parsed_date: user.date_of_birth = parsed_date else: raise ValueError("Invalid date format") except ValueError: logger.error(f"Invalid date format: {date_of_birth}") return Response({"error": "Invalid date format. Use YYYY-MM-DD."}, status=status.HTTP_400_BAD_REQUEST) user.female = request.data.get('female', user.female) user.save() logger.debug(f"User updated: firstname={user.firstname}, lastname={user.lastname}, date_of_birth={user.date_of_birth}, female={user.female}") # Memberインスタンスも更新 serializer = self.get_serializer(instance, data=request.data, partial=True) serializer.is_valid(raise_exception=True) self.perform_update(serializer) # 更新後のデータを取得 updated_instance = self.get_object() updated_serializer = self.get_serializer(updated_instance) logger.debug(f"Updated user data: {updated_serializer.data}") return Response(updated_serializer.data) else: logger.debug("User does not have dummy email, update not allowed") return Response({"error": "このユーザーの情報は更新できません。"}, status=status.HTTP_403_FORBIDDEN) def perform_update(self, serializer): serializer.save() logger.debug("perform_update called") def get_object(self): queryset = self.get_queryset() member_id = self.kwargs['pk'] obj = get_object_or_404(queryset, id=member_id) 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] def get_queryset(self): user = self.request.user return Entry.objects.filter(owner=user) class OwnerTeamsView(generics.ListAPIView): serializer_class = TeamSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): user = self.request.user return Team.objects.filter(owner=user) class OwnerMembersView(generics.ListAPIView): serializer_class = MemberSerializer permission_classes = [permissions.IsAuthenticated] def get_queryset(self): user = self.request.user return Member.objects.filter(team__owner=user) class MemberAddView(APIView): def post(self, request, team_id): logger.info(f"Received request to add member to team {team_id}") logger.debug(f"Request data: {request.data}") team = get_object_or_404(Team, id=team_id) logger.info(f"Found team: {team}") serializer = MemberSerializer(data=request.data) if serializer.is_valid(): logger.info("Serializer is valid") try: member = serializer.save(team=team) logger.info(f"Member added successfully: {member}") return Response(serializer.data, status=status.HTTP_201_CREATED) except Exception as e: logger.error(f"Error saving member: {str(e)}") return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST) else: logger.error(f"Serializer errors: {serializer.errors}") return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class TempUserViewSet(viewsets.ModelViewSet): queryset = TempUser.objects.all() serializer_class = TempUserSerializer permission_classes = [IsAuthenticated] # CustomUserViewSetの修正 class CustomUserViewSet(viewsets.ModelViewSet): queryset = CustomUser.objects.all() serializer_class = CustomUserSerializer permission_classes = [IsAuthenticated] def get_queryset(self): user = self.request.user if user.is_staff: return CustomUser.objects.all() return CustomUser.objects.filter(id=user.id) class TeamMembersView(generics.ListAPIView): serializer_class = MemberSerializer permission_classes = [IsAuthenticated] def get_queryset(self): team_id = self.kwargs['team_id'] return Member.objects.filter(team_id=team_id) # ユーザーのエントリーを取得するビュー class UserEntriesView(generics.ListAPIView): serializer_class = EntrySerializer permission_classes = [IsAuthenticated] def get_queryset(self): user = self.request.user return Entry.objects.filter(team__owner=user) # イベントのカテゴリーを取得するビュー class EventCategoriesView(generics.ListAPIView): serializer_class = NewCategorySerializer permission_classes = [IsAuthenticated] def get_queryset(self): event_id = self.kwargs['event_id'] return NewCategory.objects.filter(entry__event_id=event_id).distinct() # ユーザー仮登録 class RegisterView(APIView): def post(self, request): serializer = TempUserSerializer(data=request.data) if serializer.is_valid(): temp_user = serializer.save() verification_code = uuid.uuid4() temp_user.verification_code = verification_code temp_user.save() verification_url = request.build_absolute_uri( reverse('verify-email', kwargs={'verification_code': verification_code}) ) send_verification_email(temp_user,verifiction_url) #send_mail( # 'Verify your email', # f'Click the link to verify your email: {verification_url}', # settings.DEFAULT_FROM_EMAIL, # [temp_user.email], # fail_silently=False, #) return Response({'message': 'Verification email sent'}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class ResendInvitationEmailView(APIView): def post(self, request): email = request.data.get('email') if not email: return Response({"error": "メールアドレスを指定してください。"}, status=status.HTTP_400_BAD_REQUEST) try: temp_user = TempUser.objects.get(email=email) verification_url = request.build_absolute_uri( reverse('verify-email', kwargs={'verification_code': temp_user.verification_code}) ) send_verification_email(temp_user, verification_url) logger.info(f"招待メールを再送信しました。Email: {email}") return Response({"message": "招待メールを再送信しました。"}, status=status.HTTP_200_OK) except ObjectDoesNotExist: logger.warning(f"仮登録されていないメールアドレスに対して招待メールの再送信が試みられました。Email: {email}") return Response({"error": "指定されたメールアドレスは仮登録されていません。"}, status=status.HTTP_404_NOT_FOUND) class TempUserRegistrationView(APIView): def post(self, request): email = request.data.get('email') # 本登録済みのユーザーチェック if CustomUser.objects.filter(email=email).exists(): logger.warning(f"既に本登録されているメールアドレスでの仮登録が試みられました。Email: {email}") return Response({"error": "このメールアドレスは既に本登録されています。"}, status=status.HTTP_400_BAD_REQUEST) # 仮登録済みのユーザーチェック try: temp_user = TempUser.objects.get(email=email) verification_url = request.build_absolute_uri( reverse('verify-email', kwargs={'verification_code': temp_user.verification_code}) ) send_verification_email(temp_user, verification_url) logger.info(f"既に仮登録されているユーザーに招待メールを再送信しました。Email: {email}") return Response({"message": "既に仮登録は行われていますが、招待メールを再送信しました。"}, status=status.HTTP_200_OK) except TempUser.DoesNotExist: # 新規仮登録 serializer = TempUserRegistrationSerializer(data=request.data) if serializer.is_valid(): temp_user = serializer.save() verification_code = uuid.uuid4() temp_user.verification_code = verification_code temp_user.save() verification_url = request.build_absolute_uri( reverse('verify-email', kwargs={'verification_code': verification_code}) ) send_verification_email(temp_user, verification_url) logger.info(f"新規ユーザーを仮登録し、招待メールを送信しました。Email: {email}") return Response({"message": "仮登録が完了しました。招待メールを送信しました。"}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) #serializer = TempUserRegistrationSerializer(data=request.data) #if serializer.is_valid(): # temp_user = serializer.save() # verification_code = uuid.uuid4() # temp_user.verification_code = verification_code # temp_user.save() # verification_url = request.build_absolute_uri( # reverse('verify-email', kwargs={'verification_code': verification_code}) # ) # send_verification_email(temp_user,verification_url) #招待メールを送る。 # return Response({"message": "仮登録が完了しました。招待メールを送信しました。"}, status=status.HTTP_201_CREATED) #return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # アクティベーション class VerifyEmailView(APIView): def get(self, request, verification_code): try: temp_user = TempUser.objects.get(verification_code=verification_code) if temp_user.is_valid(): user_data = { 'email': temp_user.email, 'is_rogaining': temp_user.is_rogaining, 'zekken_number': temp_user.zekken_number, 'event_code': temp_user.event_code, 'team_name': temp_user.team_name, 'group': temp_user.group, 'firstname': temp_user.firstname, 'lastname': temp_user.lastname, 'date_of_birth': temp_user.date_of_birth, 'female': temp_user.female, } # CustomUserを作成 user = CustomUser.objects.create_user( email=user_data['email'], password=temp_user.password, **{k: v for k, v in user_data.items() if k != 'email'} ) # チームへの追加処理(もし必要なら) 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: message = "確認リンクの有効期限が切れています。アプリから認証コードの再送信をしてください。" return render(request, 'verification_success.html', {'message': message}) except TempUser.DoesNotExist: message = "無効な確認コードです。" return render(request, 'verification_success.html', {'message': message}) class MemberUserDetailView(generics.RetrieveAPIView): serializer_class = MemberWithUserSerializer permission_classes = [IsAuthenticated] def get_queryset(self): return Member.objects.select_related('user', 'team') class TeamMembersWithUserView(generics.ListAPIView): serializer_class = MemberWithUserSerializer permission_classes = [IsAuthenticated] def get_queryset(self): team_id = self.kwargs['team_id'] return Member.objects.filter(team_id=team_id).select_related('user', 'team')