Basic release 1-Aug-2024
This commit is contained in:
@ -176,7 +176,8 @@ REST_FRAMEWORK = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
FRONTEND_URL = 'http://rogainig.intranet.sumasen.net/' # フロントエンドのURLに適宜変更してください
|
#FRONTEND_URL = 'https://rogaining.intranet.sumasen.net' # フロントエンドのURLに適宜変更してください
|
||||||
|
FRONTEND_URL = 'https://rogaining.sumasen.net' # フロントエンドのURLに適宜変更してください
|
||||||
|
|
||||||
# この設定により、メールは実際には送信されず、代わりにコンソールに出力されます。
|
# この設定により、メールは実際には送信されず、代わりにコンソールに出力されます。
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
@ -186,10 +187,12 @@ EMAIL_PORT = 587
|
|||||||
EMAIL_USE_TLS = True
|
EMAIL_USE_TLS = True
|
||||||
EMAIL_HOST_USER = 'rogaining@gifuai.net'
|
EMAIL_HOST_USER = 'rogaining@gifuai.net'
|
||||||
EMAIL_HOST_PASSWORD = 'ctcpy9823"x~'
|
EMAIL_HOST_PASSWORD = 'ctcpy9823"x~'
|
||||||
DEFAULT_FROM_EMAIL = 'info@gifuai.net'
|
DEFAULT_FROM_EMAIL = 'rogaining@gifuai.net'
|
||||||
|
|
||||||
APP_DOWNLOAD_LINK = 'http://your-app-download-link.com'
|
APP_DOWNLOAD_LINK = 'https://apps.apple.com/jp/app/%E5%B2%90%E9%98%9C%E3%83%8A%E3%83%93/id6444221792'
|
||||||
SERVICE_NAME = '岐阜ロゲ'
|
ANDROID_DOWNLOAD_LINK = 'https://play.google.com/store/apps/details?id=com.dvox.gifunavi&hl=ja'
|
||||||
|
|
||||||
|
SERVICE_NAME = '岐阜ナビ(岐阜ロゲのアプリ)'
|
||||||
|
|
||||||
# settings.py
|
# settings.py
|
||||||
DEFAULT_CHARSET = 'utf-8'
|
DEFAULT_CHARSET = 'utf-8'
|
||||||
|
|||||||
33
rog/migrations/0040_auto_20240801_1310.py
Normal file
33
rog/migrations/0040_auto_20240801_1310.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2024-08-01 04:10
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0039_auto_20240726_1508'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='date_of_birth',
|
||||||
|
field=models.DateField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='female',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='firstname',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='lastname',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -301,6 +301,11 @@ class Team(models.Model):
|
|||||||
class Member(models.Model):
|
class Member(models.Model):
|
||||||
team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='members')
|
team = models.ForeignKey(Team, on_delete=models.CASCADE, related_name='members')
|
||||||
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
|
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
|
||||||
|
firstname = models.CharField(max_length=255, blank=True, null=True)
|
||||||
|
lastname = models.CharField(max_length=255, blank=True, null=True)
|
||||||
|
date_of_birth = models.DateField(null=True, blank=True)
|
||||||
|
female = models.BooleanField(default=False)
|
||||||
|
|
||||||
is_temporary = models.BooleanField(default=False) # Akira 2024-7-24
|
is_temporary = models.BooleanField(default=False) # Akira 2024-7-24
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@ -481,8 +481,8 @@ class MemberCreationSerializer(serializers.Serializer):
|
|||||||
#email = serializers.EmailField()
|
#email = serializers.EmailField()
|
||||||
email = serializers.EmailField(allow_blank=True, required=False)
|
email = serializers.EmailField(allow_blank=True, required=False)
|
||||||
|
|
||||||
firstname = serializers.CharField(required=False)
|
firstname = serializers.CharField(required=False, allow_blank=True)
|
||||||
lastname = serializers.CharField(required=False)
|
lastname = serializers.CharField(required=False, allow_blank=True)
|
||||||
date_of_birth = serializers.DateField(required=False)
|
date_of_birth = serializers.DateField(required=False)
|
||||||
female = serializers.BooleanField(required=False)
|
female = serializers.BooleanField(required=False)
|
||||||
|
|
||||||
@ -495,7 +495,80 @@ class MemberWithUserSerializer(serializers.ModelSerializer):
|
|||||||
fields = ['user', 'team']
|
fields = ['user', 'team']
|
||||||
|
|
||||||
class MemberSerializer(serializers.ModelSerializer):
|
class MemberSerializer(serializers.ModelSerializer):
|
||||||
|
email = serializers.EmailField(write_only=True)
|
||||||
|
firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
||||||
|
lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
||||||
|
date_of_birth = serializers.DateField(required=False, allow_null=True)
|
||||||
|
female = serializers.BooleanField(required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Member
|
||||||
|
fields = ['id', 'email', 'firstname', 'lastname', 'date_of_birth', 'female']
|
||||||
|
|
||||||
|
def validate_firstname(self, value):
|
||||||
|
return value or None
|
||||||
|
|
||||||
|
def validate_lastname(self, value):
|
||||||
|
return value or None
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
email = validated_data.pop('email')
|
||||||
|
team = self.context['team']
|
||||||
|
|
||||||
|
# 既存のユーザーを探すか、新しいユーザーを作成
|
||||||
|
user, created = CustomUser.objects.get_or_create(email=email)
|
||||||
|
|
||||||
|
# ユーザーが新しく作成された場合のみ、追加情報を更新
|
||||||
|
if created:
|
||||||
|
user.firstname = validated_data.get('firstname', '')
|
||||||
|
user.lastname = validated_data.get('lastname', '')
|
||||||
|
user.date_of_birth = validated_data.get('date_of_birth')
|
||||||
|
user.female = validated_data.get('female', False)
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
# メンバーを作成
|
||||||
|
member = Member.objects.create(
|
||||||
|
user=user,
|
||||||
|
team=team,
|
||||||
|
firstname=validated_data.get('firstname'),
|
||||||
|
lastname=validated_data.get('lastname'),
|
||||||
|
date_of_birth=validated_data.get('date_of_birth'),
|
||||||
|
female=validated_data.get('female', False)
|
||||||
|
)
|
||||||
|
|
||||||
|
return member
|
||||||
|
# メンバーを作成して返す
|
||||||
|
#class MemberCreationSerializerreturn Member.objects.create(user=user, team=team)
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
user_data = validated_data.pop('user', {})
|
||||||
|
user = instance.user
|
||||||
|
|
||||||
|
for attr, value in user_data.items():
|
||||||
|
setattr(user, attr, value)
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
def to_representation(self, instance):
|
||||||
|
representation = super().to_representation(instance)
|
||||||
|
representation['email'] = instance.user.email
|
||||||
|
representation['firstname'] = instance.user.firstname
|
||||||
|
representation['lastname'] = instance.user.lastname
|
||||||
|
representation['date_of_birth'] = instance.user.date_of_birth
|
||||||
|
representation['female'] = instance.user.female
|
||||||
|
return representation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class MemberSerializerOld(serializers.ModelSerializer):
|
||||||
user = CustomUserSerializer(read_only=True)
|
user = CustomUserSerializer(read_only=True)
|
||||||
|
firstname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
||||||
|
lastname = serializers.CharField(required=False, allow_blank=True, allow_null=True)
|
||||||
|
date_of_birth = serializers.DateField(required=False, allow_null=True)
|
||||||
|
female = serializers.BooleanField(required=False)
|
||||||
|
|
||||||
|
|
||||||
#team = TeamDetailSerializer(read_only=True)
|
#team = TeamDetailSerializer(read_only=True)
|
||||||
|
|
||||||
#email = serializers.EmailField(write_only=True, required=False)
|
#email = serializers.EmailField(write_only=True, required=False)
|
||||||
@ -506,8 +579,8 @@ class MemberSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Member
|
model = Member
|
||||||
fields = ['id','user','team'] # ,'email','firstname','lastname','date_of_birth','female']
|
fields = ['id','email','firstname','lastname','date_of_birth','female']
|
||||||
read_only_fields = ['id', 'team']
|
#read_only_fields = ['id', 'team']
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -530,6 +603,25 @@ class MemberSerializer(serializers.ModelSerializer):
|
|||||||
return member
|
return member
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
email = validated_data.pop('email')
|
||||||
|
team = self.context['team']
|
||||||
|
|
||||||
|
# 既存のユーザーを探すか、新しいユーザーを作成
|
||||||
|
user, created = CustomUser.objects.get_or_create(email=email)
|
||||||
|
|
||||||
|
# メンバーを作成
|
||||||
|
member = Member.objects.create(
|
||||||
|
user=user,
|
||||||
|
team=team,
|
||||||
|
firstname=validated_data.get('firstname', ''),
|
||||||
|
lastname=validated_data.get('lastname', ''),
|
||||||
|
date_of_birth=validated_data.get('date_of_birth'),
|
||||||
|
female=validated_data.get('female', False)
|
||||||
|
)
|
||||||
|
|
||||||
|
return member
|
||||||
|
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
user_data = validated_data.pop('user', {})
|
user_data = validated_data.pop('user', {})
|
||||||
@ -551,6 +643,12 @@ class MemberSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
#return super().update(instance, validated_data)
|
#return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
def to_representation(self, instance):
|
||||||
|
representation = super().to_representation(instance)
|
||||||
|
representation['email'] = instance.user.email
|
||||||
|
return representation
|
||||||
|
|
||||||
|
'''
|
||||||
def to_representation(self, instance):
|
def to_representation(self, instance):
|
||||||
representation = super().to_representation(instance)
|
representation = super().to_representation(instance)
|
||||||
user_data = representation['user']
|
user_data = representation['user']
|
||||||
@ -563,7 +661,7 @@ class MemberSerializer(serializers.ModelSerializer):
|
|||||||
'female': user_data['female'],
|
'female': user_data['female'],
|
||||||
'team': representation['team']
|
'team': representation['team']
|
||||||
}
|
}
|
||||||
|
'''
|
||||||
|
|
||||||
class EntryMemberSerializer(serializers.ModelSerializer):
|
class EntryMemberSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
32
rog/templates/activation-template.html
Normal file
32
rog/templates/activation-template.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ja">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>アクティベーション成功</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="message">
|
||||||
|
<h1>アクティベーション成功</h1>
|
||||||
|
<p>{{ message }}</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -12,6 +12,7 @@
|
|||||||
リンクをタップすると、アプリからログインすることができるようになります。
|
リンクをタップすると、アプリからログインすることができるようになります。
|
||||||
|
|
||||||
ログインした後は、チーム編成やエントリーまたはチームへの参加を行ってください。
|
ログインした後は、チーム編成やエントリーまたはチームへの参加を行ってください。
|
||||||
|
すでにメンバーとして登録されている場合には、自動的にメンバー登録されます。
|
||||||
なお、リアルロゲイニングは別途申し込みが必要になりますので、ご連絡をお待ちください。
|
なお、リアルロゲイニングは別途申し込みが必要になりますので、ご連絡をお待ちください。
|
||||||
|
|
||||||
それでは、岐阜ロゲアプリ「岐阜ナビ」をお楽しみください。
|
それでは、岐阜ロゲアプリ「岐阜ナビ」をお楽しみください。
|
||||||
|
|||||||
32
rog/templates/verification-template.html
Normal file
32
rog/templates/verification-template.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ja">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>メール確認成功</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.message {
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="message">
|
||||||
|
<h1>メール確認成功</h1>
|
||||||
|
<p>{{ message }}</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -1,7 +1,7 @@
|
|||||||
from sys import prefix
|
from sys import prefix
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from .views import LocationViewSet, Location_lineViewSet, Location_polygonViewSet, Jpn_Main_PerfViewSet, LocationsInPerf, ExtentForSubPerf, SubPerfInMainPerf, ExtentForMainPerf, LocationsInSubPerf, CatView, RegistrationAPI, LoginAPI, UserAPI, UserActionViewset, UserMakeActionViewset, UserDestinations, UpdateOrder, LocationInBound, DeleteDestination, CustomAreaLocations, GetAllGifuAreas, CustomAreaNames, userDetials, UserTracksViewSet, CatByCity, ChangePasswordView, GoalImageViewSet, CheckinImageViewSet, ExtentForLocations, DeleteAccount, PrivacyView, RegistrationView, TeamViewSet,MemberViewSet,EntryViewSet,RegisterView, VerifyEmailView, NewEventListView,NewEvent2ListView,NewCategoryListView,CategoryListView, MemberUserDetailView, TeamMembersWithUserView,MemberAddView,UserActivationView,RegistrationView,TempUserRegistrationView,ResendInvitationEmailView,update_user_info
|
from .views import LocationViewSet, Location_lineViewSet, Location_polygonViewSet, Jpn_Main_PerfViewSet, LocationsInPerf, ExtentForSubPerf, SubPerfInMainPerf, ExtentForMainPerf, LocationsInSubPerf, CatView, RegistrationAPI, LoginAPI, UserAPI, UserActionViewset, UserMakeActionViewset, UserDestinations, UpdateOrder, LocationInBound, DeleteDestination, CustomAreaLocations, GetAllGifuAreas, CustomAreaNames, userDetials, UserTracksViewSet, CatByCity, ChangePasswordView, GoalImageViewSet, CheckinImageViewSet, ExtentForLocations, DeleteAccount, PrivacyView, RegistrationView, TeamViewSet,MemberViewSet,EntryViewSet,RegisterView, VerifyEmailView, NewEventListView,NewEvent2ListView,NewCategoryListView,CategoryListView, MemberUserDetailView, TeamMembersWithUserView,MemberAddView,UserActivationView,RegistrationView,TempUserRegistrationView,ResendInvitationEmailView,update_user_info,update_user_detail,ActivateMemberView, ActivateNewMemberView
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from knox import views as knox_views
|
from knox import views as knox_views
|
||||||
|
|
||||||
@ -34,6 +34,7 @@ router.register(prefix='checkinimage', viewset=CheckinImageViewSet, basename='ch
|
|||||||
router.register(r'entry', EntryViewSet, basename='entry')
|
router.register(r'entry', EntryViewSet, basename='entry')
|
||||||
router.register(r'teams', TeamViewSet, basename='team')
|
router.register(r'teams', TeamViewSet, basename='team')
|
||||||
router.register(r'members', MemberViewSet, basename='member')
|
router.register(r'members', MemberViewSet, basename='member')
|
||||||
|
router.register(r'teams/(?P<team_id>\d+)/members', MemberViewSet, basename='team-members')
|
||||||
|
|
||||||
|
|
||||||
# Akira 追加
|
# Akira 追加
|
||||||
@ -86,5 +87,8 @@ urlpatterns += [
|
|||||||
#path('register/temp/', RegisterView.as_view(), name='register'), # 古い仮登録
|
#path('register/temp/', RegisterView.as_view(), name='register'), # 古い仮登録
|
||||||
path('reactivate/<str:activation_token>/',ResendInvitationEmailView.as_view(),name='reactivate'),
|
path('reactivate/<str:activation_token>/',ResendInvitationEmailView.as_view(),name='reactivate'),
|
||||||
path('userinfo/<int:user_id>/', update_user_info, name='update_user_info'),
|
path('userinfo/<int:user_id>/', update_user_info, name='update_user_info'),
|
||||||
path('userdetail/<int:user_id>/',update_user_info, name='update_user_detail')
|
path('userdetail/<int:user_id>/',update_user_detail, name='update_user_detail'),
|
||||||
|
path('activate-member/<int:user_id>/<int:team_id>/', ActivateMemberView.as_view(), name='activate-member'),
|
||||||
|
path('activate-new-member/<uuid:verification_code>/<int:team_id>/', ActivateNewMemberView.as_view(), name='activate-new-member'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
26
rog/utils.py
26
rog/utils.py
@ -3,6 +3,8 @@ from django.template.loader import render_to_string
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import logging
|
import logging
|
||||||
from django.core.mail import send_mail
|
from django.core.mail import send_mail
|
||||||
|
from django.urls import reverse
|
||||||
|
import uuid
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -46,7 +48,12 @@ def send_verification_email(user, activation_link):
|
|||||||
|
|
||||||
# 既にユーザーになっている人にチームへの参加要請メールを出す。
|
# 既にユーザーになっている人にチームへの参加要請メールを出す。
|
||||||
#
|
#
|
||||||
def send_team_join_email(sender,user,team,activation_link):
|
def send_team_join_email(sender,user,team):
|
||||||
|
activation_link = request.build_absolute_uri(
|
||||||
|
reverse('activate-member', args=[user.id, team.id])
|
||||||
|
)
|
||||||
|
logger.info(f"request: {request}")
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'name': user.lastname or user.email,
|
'name': user.lastname or user.email,
|
||||||
'invitor': sender.lastname,
|
'invitor': sender.lastname,
|
||||||
@ -63,22 +70,31 @@ def send_team_join_email(sender,user,team,activation_link):
|
|||||||
# その人がユーザー登録して、ユーザー登録されるとメンバーになる。
|
# その人がユーザー登録して、ユーザー登録されるとメンバーになる。
|
||||||
# アプリからユーザー登録するため、アプリのダウンロードリンクも送る。
|
# アプリからユーザー登録するため、アプリのダウンロードリンクも送る。
|
||||||
#
|
#
|
||||||
def send_invitation_email(sender,user,team,activation_link):
|
def send_invitation_email(sender,request,user_email,team):
|
||||||
|
|
||||||
|
verification_code = uuid.uuid4() # UUIDを生成
|
||||||
|
activation_link = request.build_absolute_uri(
|
||||||
|
reverse('activate-new-member', args=[verification_code, team.id])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'name': user.firstname or user.email,
|
'name': user_email,
|
||||||
'invitor': sender.lastname,
|
'invitor': sender.lastname,
|
||||||
|
'team_name': team.team_name,
|
||||||
|
'activation_link': activation_link,
|
||||||
'app_download_link': settings.APP_DOWNLOAD_LINK,
|
'app_download_link': settings.APP_DOWNLOAD_LINK,
|
||||||
'android_download_link': settings.ANDROID_DOWNLOAD_LINK,
|
'android_download_link': settings.ANDROID_DOWNLOAD_LINK,
|
||||||
}
|
}
|
||||||
|
|
||||||
subject, body = load_email_template('invitation_new_email.txt', context)
|
subject, body = load_email_template('invitation_new_email.txt', context)
|
||||||
share_send_email(subject,body,user.email)
|
share_send_email(subject,body,user_email)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 招待された後にユーザー登録された場合、ヴェリフィケーションでチーム参加登録される。
|
# 招待された後にユーザー登録された場合、ヴェリフィケーションでチーム参加登録される。
|
||||||
#
|
#
|
||||||
def send_invitaion_and_verification_email(sender, user, team, activation_link):
|
def send_invitaion_and_verification_email(user, team, activation_link):
|
||||||
context = {
|
context = {
|
||||||
'name': user.firstname or user.email,
|
'name': user.firstname or user.email,
|
||||||
'activation_link': activation_link,
|
'activation_link': activation_link,
|
||||||
|
|||||||
302
rog/views.py
302
rog/views.py
@ -1,3 +1,4 @@
|
|||||||
|
import requests
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
@ -158,6 +159,7 @@ def update_user_detail(request, user_id):
|
|||||||
setattr(user, field, data[field])
|
setattr(user, field, data[field])
|
||||||
new_value = getattr(user, field)
|
new_value = getattr(user, field)
|
||||||
if old_value != new_value:
|
if old_value != new_value:
|
||||||
|
logger.debug(f"{field}: {old_value} -> {new_value}")
|
||||||
updated_fields.append(f"{field}: {old_value} -> {new_value}")
|
updated_fields.append(f"{field}: {old_value} -> {new_value}")
|
||||||
|
|
||||||
logger.debug(f"Fields to be updated: {updated_fields}")
|
logger.debug(f"Fields to be updated: {updated_fields}")
|
||||||
@ -167,6 +169,12 @@ def update_user_detail(request, user_id):
|
|||||||
|
|
||||||
logger.info(f"User {user_id} updated. Changed fields: {', '.join(updated_fields)}")
|
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)
|
serializer = CustomUserSerializer(user)
|
||||||
|
|
||||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||||
@ -832,20 +840,8 @@ class NewEventListView(generics.ListAPIView):
|
|||||||
serializer_class = NewEventSerializer
|
serializer_class = NewEventSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def update_external_system(zekken_number, event_code, team_name, class_name, password):
|
|
||||||
api_url = f"{settings.FRONTEND_URL}/gifuroge/update_team_name"
|
|
||||||
data = {
|
|
||||||
"zekken_number": zekken_number,
|
|
||||||
"new_team_name": team_name,
|
|
||||||
"event_code": event_code
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
response = requests.post(api_url, json=data)
|
|
||||||
response.raise_for_status()
|
|
||||||
return True
|
|
||||||
except requests.RequestException as e:
|
|
||||||
logger.error(f"Failed to update external system. Error: {str(e)}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
class TeamViewSet(viewsets.ModelViewSet):
|
class TeamViewSet(viewsets.ModelViewSet):
|
||||||
serializer_class = TeamSerializer
|
serializer_class = TeamSerializer
|
||||||
@ -855,6 +851,8 @@ class TeamViewSet(viewsets.ModelViewSet):
|
|||||||
return Team.objects.filter(owner=self.request.user)
|
return Team.objects.filter(owner=self.request.user)
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
|
logger.info(f"Creating new team for user: {self.request.user.email}")
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
|
|
||||||
category = serializer.validated_data['category']
|
category = serializer.validated_data['category']
|
||||||
@ -864,12 +862,12 @@ class TeamViewSet(viewsets.ModelViewSet):
|
|||||||
category.save()
|
category.save()
|
||||||
category.refresh_from_db() # F() 式の結果を評価
|
category.refresh_from_db() # F() 式の結果を評価
|
||||||
|
|
||||||
serializer.save(owner=self.request.user, zekken_number=zekken_number)
|
team = serializer.save(owner=self.request.user, zekken_number=zekken_number)
|
||||||
|
logger.info(f"Team created successfully: {team.id}")
|
||||||
team = self.get_object()
|
|
||||||
|
|
||||||
# 外部システムの更新
|
# 外部システムの更新
|
||||||
success = update_external_system(
|
success = self.register_team(
|
||||||
|
team.owner,
|
||||||
team.zekken_number,
|
team.zekken_number,
|
||||||
team.owner.event_code,
|
team.owner.event_code,
|
||||||
team.team_name,
|
team.team_name,
|
||||||
@ -877,21 +875,93 @@ class TeamViewSet(viewsets.ModelViewSet):
|
|||||||
team.owner.password
|
team.owner.password
|
||||||
)
|
)
|
||||||
if not success:
|
if not success:
|
||||||
|
logger.error("Failed to register external system")
|
||||||
raise serializers.ValidationError("外部システムの更新に失敗しました。")
|
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):
|
def destroy(self, request, *args, **kwargs):
|
||||||
team = self.get_object()
|
team = self.get_object()
|
||||||
if team.members.exists():
|
if team.members.exists():
|
||||||
return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response(
|
||||||
|
{
|
||||||
|
"error": "チームにメンバーが残っているため削除できません。",
|
||||||
|
"error_code": "TEAM_HAS_MEMBERS"
|
||||||
|
},
|
||||||
|
status=status.HTTP_400_BAD_REQUEST
|
||||||
|
)
|
||||||
|
|
||||||
|
#return Response({"error": "チームにメンバーが残っているため削除できません。"}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
return super().destroy(request, *args, **kwargs)
|
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):
|
def update(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
return super().update(request, *args, **kwargs)
|
partial = kwargs.pop('partial', False)
|
||||||
|
instance = self.get_object()
|
||||||
|
serializer = self.get_serializer(instance, data=request.data, partial=partial)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
self.perform_update(serializer)
|
||||||
|
|
||||||
|
if getattr(instance, '_prefetched_objects_cache', None):
|
||||||
|
instance._prefetched_objects_cache = {}
|
||||||
|
|
||||||
|
return Response(serializer.data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return Response({"error": "更新に失敗しました。競合が発生した可能性があります。"}, status=status.HTTP_409_CONFLICT)
|
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):
|
def perform_update(self, serializer):
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
team = serializer.save()
|
team = serializer.save()
|
||||||
@ -906,7 +976,8 @@ class TeamViewSet(viewsets.ModelViewSet):
|
|||||||
)
|
)
|
||||||
if not success:
|
if not success:
|
||||||
raise serializers.ValidationError("外部システムの更新に失敗しました。")
|
raise serializers.ValidationError("外部システムの更新に失敗しました。")
|
||||||
|
else:
|
||||||
|
print("岐阜ロゲシステム更新に成功")
|
||||||
|
|
||||||
@action(detail=True, methods=['post'])
|
@action(detail=True, methods=['post'])
|
||||||
def copy(self, request, pk=None):
|
def copy(self, request, pk=None):
|
||||||
@ -1004,27 +1075,6 @@ class EntryViewSet(viewsets.ModelViewSet):
|
|||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(owner=self.request.user)
|
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):
|
def update(self, request, *args, **kwargs):
|
||||||
logger.info(f"Update method called for Entry with ID: {kwargs.get('pk')}")
|
logger.info(f"Update method called for Entry with ID: {kwargs.get('pk')}")
|
||||||
@ -1074,7 +1124,7 @@ class EntryViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class MemberViewSet(viewsets.ModelViewSet):
|
class MemberViewSet(viewsets.ModelViewSet):
|
||||||
#serializer_class = MemberSerializer
|
serializer_class = MemberSerializer
|
||||||
permission_classes = [permissions.IsAuthenticated,IsTeamOwner]
|
permission_classes = [permissions.IsAuthenticated,IsTeamOwner]
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
@ -1086,12 +1136,64 @@ class MemberViewSet(viewsets.ModelViewSet):
|
|||||||
team_id = self.kwargs['team_id']
|
team_id = self.kwargs['team_id']
|
||||||
return Member.objects.filter(team_id=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):
|
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'])
|
team = Team.objects.get(id=self.kwargs['team_id'])
|
||||||
serializer = self.get_serializer(data=request.data)
|
#serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer = self.get_serializer(data=request.data, context={'team': team})
|
||||||
|
|
||||||
|
try:
|
||||||
serializer.is_valid(raise_exception=True)
|
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', '')
|
email = serializer.validated_data.get('email', '')
|
||||||
|
logger.info(f"Processing member with email: {email}")
|
||||||
|
|
||||||
user_data = {
|
user_data = {
|
||||||
'firstname': serializer.validated_data.get('firstname', ''),
|
'firstname': serializer.validated_data.get('firstname', ''),
|
||||||
@ -1100,8 +1202,18 @@ class MemberViewSet(viewsets.ModelViewSet):
|
|||||||
'female': serializer.validated_data.get('female', False),
|
'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_'):
|
if not email or email.startswith('dummy_'):
|
||||||
|
logger.info("Processing as direct registration")
|
||||||
# 直接登録
|
# 直接登録
|
||||||
|
try:
|
||||||
if email:
|
if email:
|
||||||
user, created = CustomUser.objects.get_or_create(
|
user, created = CustomUser.objects.get_or_create(
|
||||||
email=email,
|
email=email,
|
||||||
@ -1113,27 +1225,41 @@ class MemberViewSet(viewsets.ModelViewSet):
|
|||||||
user = CustomUser.objects.create(email=dummy_email, **user_data)
|
user = CustomUser.objects.create(email=dummy_email, **user_data)
|
||||||
|
|
||||||
member = Member.objects.create(user=user, team=team)
|
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)
|
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)
|
#member = serializer.save(team=team)
|
||||||
#return Response(serializer.data, status=status.HTTP_201_CREATED)
|
#return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||||
else:
|
else:
|
||||||
|
logger.info("Processing as temporary registration")
|
||||||
|
|
||||||
# 仮登録
|
# 仮登録
|
||||||
existing_user = CustomUser.objects.filter(email=email).first()
|
existing_user = CustomUser.objects.filter(email=email).first()
|
||||||
if existing_user:
|
if existing_user:
|
||||||
|
logger.info(f"Existing user found: {existing_user.id}")
|
||||||
|
|
||||||
# 既存ユーザーの場合、チーム招待メールを送信
|
# 既存ユーザーの場合、チーム招待メールを送信
|
||||||
send_team_join_email(existing_user, team)
|
send_team_join_email(request.user,existing_user, team)
|
||||||
return Response({"message": "Invitation for your team sent to existing user."}, status=status.HTTP_200_OK)
|
return Response({"message": "Invitation for your team sent to existing user."}, status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
print("新規ユーザー")
|
logger.info("Inviting new temporary user")
|
||||||
temp_user = TempUser.objects.create(
|
|
||||||
email=email,
|
|
||||||
**user_data,
|
|
||||||
verification_code=str(uuid.uuid4())
|
|
||||||
)
|
|
||||||
send_invitation_email(temp_user, team) #仮登録済みでも確認メールを送る。
|
|
||||||
|
|
||||||
|
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)
|
return Response({"message": "Invitation email sent to the user."}, status=status.HTTP_201_CREATED)
|
||||||
|
except Exception as e:
|
||||||
|
logger.info(f"Error on Invitation email sent to: {email} : {e}")
|
||||||
|
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
@ -1252,6 +1378,59 @@ class MemberViewSet(viewsets.ModelViewSet):
|
|||||||
self.check_object_permissions(self.request, obj)
|
self.check_object_permissions(self.request, obj)
|
||||||
return 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):
|
class OwnerEntriesView(generics.ListAPIView):
|
||||||
serializer_class = EntrySerializer
|
serializer_class = EntrySerializer
|
||||||
permission_classes = [permissions.IsAuthenticated]
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
@ -1461,13 +1640,24 @@ class VerifyEmailView(APIView):
|
|||||||
password=temp_user.password,
|
password=temp_user.password,
|
||||||
**{k: v for k, v in user_data.items() if k != 'email'}
|
**{k: v for k, v in user_data.items() if k != 'email'}
|
||||||
)
|
)
|
||||||
temp_user.delete()
|
|
||||||
return Response({'message': 'Email verified and user created'}, status=status.HTTP_201_CREATED)
|
|
||||||
|
|
||||||
|
# チームへの追加処理(もし必要なら)
|
||||||
|
if hasattr(temp_user, 'team_id'):
|
||||||
|
team = Team.objects.get(id=temp_user.team_id)
|
||||||
|
Member.objects.create(user=user, team=team)
|
||||||
|
message = f"メールアドレスが確認され、アカウントが作成されました。{team.team_name}のメンバーとして登録されています。アプリでログインして、必要な情報を入力してください。"
|
||||||
else:
|
else:
|
||||||
return Response({'message': 'Verification link expired'}, status=status.HTTP_400_BAD_REQUEST)
|
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:
|
except TempUser.DoesNotExist:
|
||||||
return Response({'message': 'Invalid verification code'}, status=status.HTTP_400_BAD_REQUEST)
|
message = "無効な確認コードです。"
|
||||||
|
return render(request, 'verification_success.html', {'message': message})
|
||||||
|
|
||||||
|
|
||||||
class MemberUserDetailView(generics.RetrieveAPIView):
|
class MemberUserDetailView(generics.RetrieveAPIView):
|
||||||
|
|||||||
Reference in New Issue
Block a user