Files
rogaining_srv/rog/views.py

1277 lines
54 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,send_entry_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
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)
def LocationInBound(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'))
cat = request.GET.get('cat')
grp = request.GET.get('grp')
is_rog = request.GET.get('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)
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) > 120:
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):
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() 式の結果を評価
serializer.save(owner=self.request.user, zekken_number=zekken_number)
def destroy(self, request, *args, **kwargs):
team = self.get_object()
if team.members.exists():
return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
return super().destroy(request, *args, **kwargs)
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)
@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 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):
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)
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)
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)
email = serializer.validated_data.get('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 not email or email.startswith('dummy_'):
# 直接登録
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)
return Response(MemberSerializer(member).data, status=status.HTTP_201_CREATED)
#member = serializer.save(team=team)
#return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
# 仮登録
existing_user = CustomUser.objects.filter(email=email).first()
if existing_user:
# 既存ユーザーの場合、チーム招待メールを送信
send_team_join_email(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)
return Response({"message": "Invitation email sent to the user."}, status=status.HTTP_201_CREATED)
'''
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"))
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 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'}
)
temp_user.delete()
return Response({'message': 'Email verified and user created'}, status=status.HTTP_201_CREATED)
else:
return Response({'message': 'Verification link expired'}, status=status.HTTP_400_BAD_REQUEST)
except TempUser.DoesNotExist:
return Response({'message': 'Invalid verification code'}, status=status.HTTP_400_BAD_REQUEST)
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')