Files
rogaining_srv/rog/views.py

713 lines
29 KiB
Python

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, TempUser
from rest_framework import viewsets,status
from .serializers import LocationSerializer, Location_lineSerializer, Location_polygonSerializer, JPN_main_perfSerializer, LocationCatSerializer, CreateUserSerializer, UserSerializer, LoginUserSerializer, UseractionsSerializer, UserDestinationSerializer, GifuAreaSerializer, LocationEventNameSerializer, RogUserSerializer, UserTracksSerializer, ChangePasswordSerializer, GolaImageSerializer, CheckinImageSerializer, RegistrationSerializer, Team, Member, Entry, CustomUserSerializer
from knox.models import AuthToken
from rest_framework import viewsets, generics, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.parsers import JSONParser, MultiPartParser
from .serializers import LocationSerializer, TeamSerializer, MemberSerializer, EntrySerializer
from django.http import JsonResponse
from rest_framework.permissions import IsAuthenticated
from django.contrib.gis.db.models import Extent, Union
from .serializers import TestSerialiser
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
import uuid
from django.shortcuts import render
from django.utils import timezone
from django.db import transaction
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"]
#===== AKira ここから
class CustomUserViewSet(viewsets.ModelViewSet):
queryset = CustomUser.objects.all()
serializer_class = CustomUserSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
return CustomUser.objects.filter(id=self.request.user.id)
class TeamViewSet(viewsets.ModelViewSet):
queryset = Team.objects.all()
serializer_class = TeamSerializer
@transaction.atomic
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
# チーム登録後にエントリー登録と外部APIコールを行う
self.register_entry_and_call_external_api(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def register_entry_and_call_external_api(self, team_data):
# エントリーの登録
entry_data = {
'zekken_number': team_data['zekken_number'],
'event_code': request.data.get('event_code'), # エントリー用のevent_codeを取得
'date': request.data.get('date') # エントリー用の日付を取得
}
entry_serializer = EntrySerializer(data=entry_data)
if entry_serializer.is_valid():
entry_serializer.save()
# 外部APIへのコール
self.call_external_api(team_data, entry_data)
else:
# エントリー登録に失敗した場合のエラーハンドリング
raise serializers.ValidationError(entry_serializer.errors)
def call_external_api(self, team_data, entry_data):
external_api_url = "https://rogaining.sumasen.net/gifuroge/register_team"
payload = {
'zekken_number': team_data['zekken_number'],
'event_code': entry_data['event_code'],
'team_name': team_data['team_name'],
'class_name': team_data.get('class_name', 'Default'), # class_nameがない場合はデフォルト値を設定
'password': team_data['password']
}
try:
response = requests.post(external_api_url, data=payload)
response.raise_for_status() # エラーレスポンスの場合は例外を発生させる
# レスポンスの処理(必要に応じて)
print(f"External API response: {response.json()}")
except requests.RequestException as e:
# 外部APIコールに失敗した場合のエラーハンドリング
print(f"Failed to call external API: {str(e)}")
# ここでエラーをログに記録したり、管理者に通知したりすることができます
def get_queryset(self):
user = self.request.user
return Team.objects.filter(member__userid=user)
class MemberViewSet(viewsets.ModelViewSet):
queryset = Member.objects.all()
serializer_class = MemberSerializer
permission_classes = [IsAuthenticated]
def create(self, request):
serializer = self.get_serializer(data=request.data)
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)
def get_queryset(self):
user = self.request.user
return Member.objects.filter(userid=user)
class EntryViewSet(viewsets.ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntrySerializer
permission_classes = [IsAuthenticated]
def create(self, request):
serializer = self.get_serializer(data=request.data)
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)
def get_queryset(self):
user = self.request.user
return Entry.objects.filter(zekken_number__member__userid=user)
#===== AKira ここまで
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
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 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 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 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_old(APIView):
def post(self, request):
serializer = RegistrationSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class RegistrationView(APIView):
def post(self, request):
serializer = RegistrationSerializer(data=request.data)
if serializer.is_valid():
temp_user = serializer.save()
verification_url = request.build_absolute_uri(
reverse('verify_email', kwargs={'verification_code': temp_user.verification_code})
)
send_mail(
'Verify your email',
f'Please click the link to verify your email: {verification_url}',
settings.DEFAULT_FROM_EMAIL,
[temp_user.email],
fail_silently=False,
)
return Response({"message": "Please check your email to complete registration."}, 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 not temp_user.is_valid():
temp_user.delete()
return Response({"error": "Verification link has expired. Please register again."}, status=status.HTTP_400_BAD_REQUEST)
user = CustomUser.objects.create_user(
email=temp_user.email,
password=temp_user.password,
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
)
temp_user.delete()
return Response({"message": "Email verified. Registration complete."}, status=status.HTTP_200_OK)
except TempUser.DoesNotExist:
return Response({"error": "Invalid verification code."}, status=status.HTTP_400_BAD_REQUEST)