debugging entry
This commit is contained in:
10
rog/admin.py
10
rog/admin.py
@ -4,7 +4,7 @@ from django.shortcuts import render
|
|||||||
from leaflet.admin import LeafletGeoAdmin
|
from leaflet.admin import LeafletGeoAdmin
|
||||||
from leaflet.admin import LeafletGeoAdminMixin
|
from leaflet.admin import LeafletGeoAdminMixin
|
||||||
from leaflet_admin_list.admin import LeafletAdminListMixin
|
from leaflet_admin_list.admin import LeafletAdminListMixin
|
||||||
from .models import RogUser, Location, SystemSettings, JoinedEvent, Favorite, TravelList, TravelPoint, ShapeLayers, Event, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, CustomUser, GifuAreas, UserTracks, templocation, UserUpload, EventUser, GoalImages, CheckinImages, NewEvent, Team, Category, Entry, Member, TempUser
|
from .models import RogUser, Location, SystemSettings, JoinedEvent, Favorite, TravelList, TravelPoint, ShapeLayers, Event, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, CustomUser, GifuAreas, UserTracks, templocation, UserUpload, EventUser, GoalImages, CheckinImages, NewEvent, NewEvent2, Team, NewCategory, Category, Entry, Member, TempUser
|
||||||
from django.contrib.auth.admin import UserAdmin
|
from django.contrib.auth.admin import UserAdmin
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
@ -196,8 +196,8 @@ class TempLocationAdmin(LeafletGeoAdmin):
|
|||||||
list_display = ('location_id','cp', 'location_name', 'category', 'event_name', 'event_active', 'auto_checkin', 'checkin_radius', 'checkin_point', 'buy_point',)
|
list_display = ('location_id','cp', 'location_name', 'category', 'event_name', 'event_active', 'auto_checkin', 'checkin_radius', 'checkin_point', 'buy_point',)
|
||||||
actions = [tranfer_to_location,]
|
actions = [tranfer_to_location,]
|
||||||
|
|
||||||
@admin.register(NewEvent)
|
@admin.register(NewEvent2)
|
||||||
class NewEventAdmin(admin.ModelAdmin):
|
class NewEvent2Admin(admin.ModelAdmin):
|
||||||
list_display = ['event_name', 'start_datetime', 'end_datetime']
|
list_display = ['event_name', 'start_datetime', 'end_datetime']
|
||||||
search_fields = ['event_name']
|
search_fields = ['event_name']
|
||||||
|
|
||||||
@ -206,8 +206,8 @@ class TeamAdmin(admin.ModelAdmin):
|
|||||||
list_display = ['zekken_number', 'team_name', 'owner']
|
list_display = ['zekken_number', 'team_name', 'owner']
|
||||||
search_fields = ['zekken_number', 'team_name', 'owner__email']
|
search_fields = ['zekken_number', 'team_name', 'owner__email']
|
||||||
|
|
||||||
@admin.register(Category)
|
@admin.register(NewCategory)
|
||||||
class CategoryAdmin(admin.ModelAdmin):
|
class NewCategoryAdmin(admin.ModelAdmin):
|
||||||
list_display = ['category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']
|
list_display = ['category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']
|
||||||
list_filter = ['family', 'female']
|
list_filter = ['family', 'female']
|
||||||
search_fields = ['category_name']
|
search_fields = ['category_name']
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-09-09 13:18
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0032_alter_location_sub_loc_id'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='templocation',
|
|
||||||
name='sub_loc_id',
|
|
||||||
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
274
rog/migrations/0033_auto_20240724_1431.py
Normal file
274
rog/migrations/0033_auto_20240724_1431.py
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2024-07-24 05:31
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from django.conf import settings
|
||||||
|
import django.contrib.postgres.indexes
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0032_alter_location_sub_loc_id'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Category',
|
||||||
|
fields=[
|
||||||
|
('category_name', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||||
|
('category_number', models.IntegerField(unique=True)),
|
||||||
|
('duration', models.DurationField(default=datetime.timedelta(seconds=18000))),
|
||||||
|
('num_of_member', models.IntegerField(default=1)),
|
||||||
|
('family', models.BooleanField(default=False)),
|
||||||
|
('female', models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CheckinImages',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('checkinimage', models.FileField(blank=True, null=True, upload_to='checkin/%y%m%d')),
|
||||||
|
('checkintime', models.DateTimeField(verbose_name='Goal time')),
|
||||||
|
('team_name', models.CharField(max_length=255, verbose_name='Team name')),
|
||||||
|
('event_code', models.CharField(max_length=255, verbose_name='event code')),
|
||||||
|
('cp_number', models.IntegerField(verbose_name='CP numner')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Entry',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('date', models.DateTimeField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EntryMember',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('is_temporary', models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='GoalImages',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('goalimage', models.FileField(blank=True, null=True, upload_to='goals/%y%m%d')),
|
||||||
|
('goaltime', models.DateTimeField(verbose_name='Goal time')),
|
||||||
|
('team_name', models.CharField(max_length=255, verbose_name='Team name')),
|
||||||
|
('event_code', models.CharField(max_length=255, verbose_name='event code')),
|
||||||
|
('cp_number', models.IntegerField(verbose_name='CP numner')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Member',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('is_temporary', models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='NewEvent',
|
||||||
|
fields=[
|
||||||
|
('event_name', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
||||||
|
('start_datetime', models.DateTimeField(default=django.utils.timezone.now)),
|
||||||
|
('end_datetime', models.DateTimeField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Team',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('zekken_number', models.CharField(max_length=255, unique=True)),
|
||||||
|
('team_name', models.CharField(max_length=255)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TempUser',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('email', models.EmailField(max_length=254, unique=True)),
|
||||||
|
('password', models.CharField(max_length=128)),
|
||||||
|
('is_rogaining', models.BooleanField(default=False)),
|
||||||
|
('zekken_number', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('event_code', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('team_name', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('group', models.CharField(max_length=255)),
|
||||||
|
('firstname', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('lastname', models.CharField(blank=True, max_length=255, null=True)),
|
||||||
|
('date_of_birth', models.DateField(blank=True, null=True)),
|
||||||
|
('female', models.BooleanField(default=False)),
|
||||||
|
('verification_code', models.UUIDField(default=uuid.uuid4, editable=False)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('expires_at', models.DateTimeField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='JpnAdminPerf',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='JpnSubPerf',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='date_of_birth',
|
||||||
|
field=models.DateField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='event_code',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Event Code'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='female',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='firstname',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='is_rogaining',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='lastname',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='team_name',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Team Name'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='zekken_number',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Zekken Number'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='customuser',
|
||||||
|
name='email',
|
||||||
|
field=models.CharField(max_length=255, unique=True, verbose_name='Email'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='category',
|
||||||
|
field=models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Category'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_active',
|
||||||
|
field=models.BooleanField(db_index=True, default=True, verbose_name='Is Event active'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='event_name',
|
||||||
|
field=models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Event name'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='group',
|
||||||
|
field=models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Group'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='location',
|
||||||
|
name='location_id',
|
||||||
|
field=models.IntegerField(blank=True, db_index=True, null=True, verbose_name='Location id'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='templocation',
|
||||||
|
name='sub_loc_id',
|
||||||
|
field=models.CharField(blank=True, max_length=2048, null=True, verbose_name='Sub location id'),
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='location',
|
||||||
|
index=django.contrib.postgres.indexes.GistIndex(fields=['geom'], name='rog_locatio_geom_4793cc_gist'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='category',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='rog.category'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='owner',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='owned_teams', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='team',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='member',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='goalimages',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entrymember',
|
||||||
|
name='entry',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.entry'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entrymember',
|
||||||
|
name='member',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.member'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entry',
|
||||||
|
name='category',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.category'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entry',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entry',
|
||||||
|
name='owner',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='entry',
|
||||||
|
name='team',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='checkinimages',
|
||||||
|
name='user',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='category',
|
||||||
|
unique_together={('category_name', 'category_number')},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='team',
|
||||||
|
unique_together={('zekken_number', 'category')},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='member',
|
||||||
|
unique_together={('team', 'user')},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='entrymember',
|
||||||
|
unique_together={('entry', 'member')},
|
||||||
|
),
|
||||||
|
migrations.AlterUniqueTogether(
|
||||||
|
name='entry',
|
||||||
|
unique_together={('team', 'event', 'date', 'owner')},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-10-06 10:51
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0033_alter_templocation_sub_loc_id'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='email',
|
|
||||||
field=models.CharField(max_length=255, verbose_name='user name'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
34
rog/migrations/0034_auto_20240724_1522.py
Normal file
34
rog/migrations/0034_auto_20240724_1522.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2024-07-24 06:22
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0033_auto_20240724_1431'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='category',
|
||||||
|
name='category_number',
|
||||||
|
field=models.IntegerField(default=0),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='NewCategory',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('category_name', models.CharField(max_length=255, unique=True)),
|
||||||
|
('category_number', models.IntegerField(default=0)),
|
||||||
|
('duration', models.DurationField(default=datetime.timedelta(seconds=18000))),
|
||||||
|
('num_of_member', models.IntegerField(default=1)),
|
||||||
|
('family', models.BooleanField(default=False)),
|
||||||
|
('female', models.BooleanField(default=False)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'unique_together': {('category_name', 'category_number')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-10-06 10:52
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0034_alter_customuser_email'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='email',
|
|
||||||
field=models.EmailField(max_length=254, unique=True, verbose_name='user name'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
29
rog/migrations/0035_auto_20240724_1529.py
Normal file
29
rog/migrations/0035_auto_20240724_1529.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2024-07-24 06:29
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0034_auto_20240724_1522'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='NewEvent2',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('event_name', models.CharField(max_length=255, unique=True)),
|
||||||
|
('start_datetime', models.DateTimeField(default=django.utils.timezone.now)),
|
||||||
|
('end_datetime', models.DateTimeField()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='entry',
|
||||||
|
name='event',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent2'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-10-06 11:01
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0035_alter_customuser_email'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='email',
|
|
||||||
field=models.CharField(max_length=255, unique=True, verbose_name='Email'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
20
rog/migrations/0036_alter_team_category.py
Normal file
20
rog/migrations/0036_alter_team_category.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2024-07-24 06:58
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import rog.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0035_auto_20240724_1529'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='team',
|
||||||
|
name='category',
|
||||||
|
field=models.ForeignKey(default=rog.models.get_default_category, on_delete=django.db.models.deletion.SET_DEFAULT, to='rog.newcategory'),
|
||||||
|
),
|
||||||
|
]
|
||||||
19
rog/migrations/0037_alter_member_team.py
Normal file
19
rog/migrations/0037_alter_member_team.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 3.2.9 on 2024-07-24 15:20
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('rog', '0036_alter_team_category'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='member',
|
||||||
|
name='team',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='members', to='rog.team'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,18 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-10-06 13:42
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0036_alter_customuser_email'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='is_rogaining',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-10-16 10:50
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0037_customuser_is_rogaining'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='event_code',
|
|
||||||
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Event Code'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='team_name',
|
|
||||||
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Team Name'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='zekken_number',
|
|
||||||
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Zekken Number'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-10-17 11:39
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0038_auto_20221016_1950'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='GoalImages',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('goalimage', models.FileField(blank=True, null=True, upload_to='%y%m%d')),
|
|
||||||
('goaltime', models.DateTimeField(verbose_name='Goal time')),
|
|
||||||
('team_name', models.CharField(max_length=255, verbose_name='Team name')),
|
|
||||||
('event_code', models.CharField(max_length=255, verbose_name='event code')),
|
|
||||||
('cp_number', models.IntegerField(verbose_name='CP numner')),
|
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2022-11-05 10:39
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0039_goalimages'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='goalimages',
|
|
||||||
name='goalimage',
|
|
||||||
field=models.FileField(blank=True, null=True, upload_to='goals/%y%m%d'),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='CheckinImages',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('checkinimage', models.FileField(blank=True, null=True, upload_to='checkin/%y%m%d')),
|
|
||||||
('checkintime', models.DateTimeField(verbose_name='Goal time')),
|
|
||||||
('team_name', models.CharField(max_length=255, verbose_name='Team name')),
|
|
||||||
('event_code', models.CharField(max_length=255, verbose_name='event code')),
|
|
||||||
('cp_number', models.IntegerField(verbose_name='CP numner')),
|
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2023-05-26 08:24
|
|
||||||
|
|
||||||
import django.contrib.postgres.indexes
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0040_auto_20221105_1939'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.DeleteModel(
|
|
||||||
name='JpnAdminPerf',
|
|
||||||
),
|
|
||||||
migrations.DeleteModel(
|
|
||||||
name='JpnSubPerf',
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='location',
|
|
||||||
name='category',
|
|
||||||
field=models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Category'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='location',
|
|
||||||
name='event_active',
|
|
||||||
field=models.BooleanField(db_index=True, default=True, verbose_name='Is Event active'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='location',
|
|
||||||
name='event_name',
|
|
||||||
field=models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Event name'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='location',
|
|
||||||
name='group',
|
|
||||||
field=models.CharField(blank=True, db_index=True, max_length=2048, null=True, verbose_name='Group'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='location',
|
|
||||||
name='location_id',
|
|
||||||
field=models.IntegerField(blank=True, db_index=True, null=True, verbose_name='Location id'),
|
|
||||||
),
|
|
||||||
migrations.AddIndex(
|
|
||||||
model_name='location',
|
|
||||||
index=django.contrib.postgres.indexes.GistIndex(fields=['geom'], name='rog_locatio_geom_4793cc_gist'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
# Generated by Django 3.2.9 on 2024-07-22 07:03
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import django.utils.timezone
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('rog', '0041_auto_20230526_1724'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Category',
|
|
||||||
fields=[
|
|
||||||
('category_name', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
|
||||||
('category_number', models.IntegerField(unique=True)),
|
|
||||||
('duration', models.DurationField(default=datetime.timedelta(seconds=18000))),
|
|
||||||
('num_of_member', models.IntegerField(default=1)),
|
|
||||||
('family', models.BooleanField(default=False)),
|
|
||||||
('female', models.BooleanField(default=False)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'unique_together': {('category_name', 'category_number')},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='NewEvent',
|
|
||||||
fields=[
|
|
||||||
('event_name', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
|
||||||
('start_datetime', models.DateTimeField(default=django.utils.timezone.now)),
|
|
||||||
('end_datetime', models.DateTimeField()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='TempUser',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('email', models.EmailField(max_length=254, unique=True)),
|
|
||||||
('password', models.CharField(max_length=128)),
|
|
||||||
('is_rogaining', models.BooleanField(default=False)),
|
|
||||||
('zekken_number', models.CharField(blank=True, max_length=255, null=True)),
|
|
||||||
('event_code', models.CharField(blank=True, max_length=255, null=True)),
|
|
||||||
('team_name', models.CharField(blank=True, max_length=255, null=True)),
|
|
||||||
('group', models.CharField(max_length=255)),
|
|
||||||
('firstname', models.CharField(blank=True, max_length=255, null=True)),
|
|
||||||
('lastname', models.CharField(blank=True, max_length=255, null=True)),
|
|
||||||
('date_of_birth', models.DateField(blank=True, null=True)),
|
|
||||||
('female', models.BooleanField(default=False)),
|
|
||||||
('verification_code', models.UUIDField(default=uuid.uuid4, editable=False)),
|
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
|
||||||
('expires_at', models.DateTimeField()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='date_of_birth',
|
|
||||||
field=models.DateField(blank=True, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='female',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='firstname',
|
|
||||||
field=models.CharField(blank=True, max_length=255, null=True),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='customuser',
|
|
||||||
name='lastname',
|
|
||||||
field=models.CharField(blank=True, max_length=255, null=True),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Team',
|
|
||||||
fields=[
|
|
||||||
('zekken_number', models.CharField(max_length=255, primary_key=True, serialize=False)),
|
|
||||||
('team_name', models.CharField(max_length=255)),
|
|
||||||
('password', models.CharField(max_length=128)),
|
|
||||||
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Member',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team')),
|
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'unique_together': {('team', 'user')},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='Entry',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('date', models.DateTimeField()),
|
|
||||||
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.category')),
|
|
||||||
('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.newevent')),
|
|
||||||
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='rog.team')),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'unique_together': {('team', 'event', 'date')},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -261,6 +261,15 @@ class TempUser(models.Model):
|
|||||||
def is_valid(self):
|
def is_valid(self):
|
||||||
return timezone.now() <= self.expires_at
|
return timezone.now() <= self.expires_at
|
||||||
|
|
||||||
|
class NewEvent2(models.Model):
|
||||||
|
event_name = models.CharField(max_length=255, unique=True)
|
||||||
|
start_datetime = models.DateTimeField(default=timezone.now)
|
||||||
|
end_datetime = models.DateTimeField()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.event_name} - From:{self.start_datetime} To:{self.end_datetime}"
|
||||||
|
|
||||||
|
|
||||||
class NewEvent(models.Model):
|
class NewEvent(models.Model):
|
||||||
event_name = models.CharField(max_length=255, primary_key=True)
|
event_name = models.CharField(max_length=255, primary_key=True)
|
||||||
start_datetime = models.DateTimeField(default=timezone.now)
|
start_datetime = models.DateTimeField(default=timezone.now)
|
||||||
@ -269,19 +278,27 @@ class NewEvent(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.event_name} - From:{self.start_datetime} To:{self.end_datetime}"
|
return f"{self.event_name} - From:{self.start_datetime} To:{self.end_datetime}"
|
||||||
|
|
||||||
|
def get_default_category():
|
||||||
|
return NewCategory.objects.get_or_create(category_name="Default Category", category_number=1)[0].id
|
||||||
|
|
||||||
|
|
||||||
class Team(models.Model):
|
class Team(models.Model):
|
||||||
zekken_number = models.CharField(max_length=255, primary_key=True)
|
zekken_number = models.CharField(max_length=255, unique=True)
|
||||||
team_name = models.CharField(max_length=255)
|
team_name = models.CharField(max_length=255)
|
||||||
password = models.CharField(max_length=128)
|
owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE, related_name='owned_teams', blank=True, null=True)
|
||||||
owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
|
category = models.ForeignKey('NewCategory', on_delete=models.SET_DEFAULT, default=get_default_category)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('zekken_number', 'category')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.zekken_number} - {self.team_name}, owner:{self.owner.lastname} {self.owner.firstname}"
|
return f"{self.zekken_number} - {self.team_name}, owner:{self.owner.lastname} {self.owner.firstname}"
|
||||||
|
|
||||||
|
|
||||||
class Member(models.Model):
|
class Member(models.Model):
|
||||||
team = models.ForeignKey(Team, on_delete=models.CASCADE)
|
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)
|
||||||
|
is_temporary = models.BooleanField(default=False) # Akira 2024-7-24
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('team', 'user')
|
unique_together = ('team', 'user')
|
||||||
@ -292,7 +309,26 @@ class Member(models.Model):
|
|||||||
#
|
#
|
||||||
class Category(models.Model):
|
class Category(models.Model):
|
||||||
category_name = models.CharField(max_length=255, primary_key=True)
|
category_name = models.CharField(max_length=255, primary_key=True)
|
||||||
category_number = models.IntegerField(unique=True)
|
category_number = models.IntegerField(default=0)
|
||||||
|
duration = models.DurationField(default=timedelta(hours=5))
|
||||||
|
num_of_member = models.IntegerField(default=1)
|
||||||
|
family = models.BooleanField(default=False)
|
||||||
|
female = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('category_name','category_number')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
hours = self.duration.total_seconds() // 3600
|
||||||
|
return f"{self.category_name} - {self.category_number} ({int(hours)}時間)"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hours(self):
|
||||||
|
return self.duration.total_seconds() // 3600
|
||||||
|
|
||||||
|
class NewCategory(models.Model):
|
||||||
|
category_name = models.CharField(max_length=255, unique=True)
|
||||||
|
category_number = models.IntegerField(default=0)
|
||||||
duration = models.DurationField(default=timedelta(hours=5))
|
duration = models.DurationField(default=timedelta(hours=5))
|
||||||
num_of_member = models.IntegerField(default=1)
|
num_of_member = models.IntegerField(default=1)
|
||||||
family = models.BooleanField(default=False)
|
family = models.BooleanField(default=False)
|
||||||
@ -311,12 +347,13 @@ class Category(models.Model):
|
|||||||
|
|
||||||
class Entry(models.Model):
|
class Entry(models.Model):
|
||||||
team = models.ForeignKey(Team, on_delete=models.CASCADE)
|
team = models.ForeignKey(Team, on_delete=models.CASCADE)
|
||||||
event = models.ForeignKey(NewEvent, on_delete=models.CASCADE)
|
event = models.ForeignKey(NewEvent2, on_delete=models.CASCADE)
|
||||||
category = models.ForeignKey(Category, on_delete=models.CASCADE)
|
category = models.ForeignKey(NewCategory, on_delete=models.CASCADE)
|
||||||
date = models.DateTimeField()
|
date = models.DateTimeField()
|
||||||
|
owner = models.ForeignKey(CustomUser, on_delete=models.CASCADE,blank=True, null=True) # Akira 2024-7-24
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('team', 'event', 'date')
|
unique_together = ('team', 'event', 'date','owner')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.team.zekken_number} - {self.event.event_name} - {self.date}"
|
return f"{self.team.zekken_number} - {self.event.event_name} - {self.date}"
|
||||||
@ -332,9 +369,13 @@ class Entry(models.Model):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# メンバーの年齢と性別をチェック
|
# メンバーの年齢と性別をチェック
|
||||||
members = Member.objects.filter(team=self.team)
|
if self.team and not self.team.members.exists():
|
||||||
if not members.exists():
|
raise ValidationError({'team': 'チームにメンバーが登録されていません。'})
|
||||||
raise ValidationError("チームにメンバーが登録されていません。")
|
|
||||||
|
#members = Member.objects.filter(team=self.team)
|
||||||
|
#if not members.exists():
|
||||||
|
# # ここで、owner をMemberに登録する。 Akira 2024-7-24
|
||||||
|
# raise ValidationError("チームにメンバーが登録されていません。")
|
||||||
|
|
||||||
adults = [m for m in members if self.is_adult(m.user.date_of_birth)]
|
adults = [m for m in members if self.is_adult(m.user.date_of_birth)]
|
||||||
children = [m for m in members if self.is_child(m.user.date_of_birth)]
|
children = [m for m in members if self.is_child(m.user.date_of_birth)]
|
||||||
@ -387,6 +428,17 @@ class Entry(models.Model):
|
|||||||
return 13 <= age <= 17
|
return 13 <= age <= 17
|
||||||
|
|
||||||
|
|
||||||
|
class EntryMember(models.Model):
|
||||||
|
entry = models.ForeignKey(Entry, on_delete=models.CASCADE)
|
||||||
|
member = models.ForeignKey(Member, on_delete=models.CASCADE)
|
||||||
|
is_temporary = models.BooleanField(default=False) # Akira 2024-7-24
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ('entry', 'member')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.entry.team.zekken_number} - {self.member.user.lastname} {self.member.user.firstname}"
|
||||||
|
|
||||||
|
|
||||||
class GoalImages(models.Model):
|
class GoalImages(models.Model):
|
||||||
user=models.ForeignKey(CustomUser, on_delete=models.DO_NOTHING)
|
user=models.ForeignKey(CustomUser, on_delete=models.DO_NOTHING)
|
||||||
|
|||||||
@ -1,6 +1,16 @@
|
|||||||
|
|
||||||
from rest_framework import permissions
|
from rest_framework import permissions
|
||||||
|
from .models import Team,Member
|
||||||
|
|
||||||
class IsMemberOrTeamOwner(permissions.BasePermission):
|
class IsMemberOrTeamOwner(permissions.BasePermission):
|
||||||
def has_object_permission(self, request, view, obj):
|
def has_object_permission(self, request, view, obj):
|
||||||
# obj は Member インスタンス
|
# Check if user is a member of the team or the team owner
|
||||||
return request.user == obj.user or request.user == obj.team.owner
|
return request.user in obj.team.members.all() or request.user == obj.team.owner
|
||||||
|
|
||||||
|
class IsTeamOwner(permissions.BasePermission):
|
||||||
|
def has_object_permission(self, request, view, obj):
|
||||||
|
if isinstance(obj, Team):
|
||||||
|
return obj.owner == request.user
|
||||||
|
elif isinstance(obj, Member):
|
||||||
|
return obj.team.owner == request.user
|
||||||
|
return False
|
||||||
|
|||||||
@ -1,15 +1,25 @@
|
|||||||
|
import uuid
|
||||||
|
from django.db import IntegrityError
|
||||||
|
from django.core.mail import send_mail
|
||||||
|
from django.conf import settings
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from django.db import transaction
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework_gis.serializers import GeoFeatureModelSerializer
|
from rest_framework_gis.serializers import GeoFeatureModelSerializer
|
||||||
from sqlalchemy.sql.functions import mode
|
from sqlalchemy.sql.functions import mode
|
||||||
from .models import Location, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, GifuAreas, RogUser, UserTracks, GoalImages, CheckinImages,CustomUser,NewEvent, Team, Category, Entry, Member, TempUser
|
from .models import Location, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, GifuAreas, RogUser, UserTracks, GoalImages, CheckinImages,CustomUser,NewEvent,NewEvent2, Team, NewCategory, Category, Entry, Member, TempUser,EntryMember
|
||||||
from drf_extra_fields.fields import Base64ImageField
|
from drf_extra_fields.fields import Base64ImageField
|
||||||
|
|
||||||
#from django.contrib.auth.models import User
|
#from django.contrib.auth.models import User
|
||||||
from .models import CustomUser
|
from .models import CustomUser
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
from .utils import send_activation_email
|
||||||
|
|
||||||
from .models import TestModel
|
from .models import TestModel
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class LocationCatSerializer(serializers.ModelSerializer):
|
class LocationCatSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -194,15 +204,67 @@ class RegistrationSerializer(serializers.ModelSerializer):
|
|||||||
user.save()
|
user.save()
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
class NewCategorySerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = NewCategory
|
||||||
|
#fields = ['id','category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']
|
||||||
|
fields = ['id','category_name', 'category_number']
|
||||||
|
|
||||||
|
class NewEvent2Serializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = NewEvent2
|
||||||
|
fields = ['id','event_name', 'start_datetime', 'end_datetime']
|
||||||
|
|
||||||
class NewEventSerializer(serializers.ModelSerializer):
|
class NewEventSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = NewEvent
|
model = NewEvent
|
||||||
fields = ['event_name', 'start_datetime', 'end_datetime']
|
fields = ['event_name', 'start_datetime', 'end_datetime']
|
||||||
|
|
||||||
class TeamSerializer(serializers.ModelSerializer):
|
class TeamSerializer(serializers.ModelSerializer):
|
||||||
|
#category = serializers.PrimaryKeyRelatedField(queryset=NewCategory.objects.all())
|
||||||
|
|
||||||
|
category = NewCategorySerializer(read_only=True)
|
||||||
|
#category_id = serializers.PrimaryKeyRelatedField(
|
||||||
|
# queryset=NewCategory.objects.all(),
|
||||||
|
# source='category',
|
||||||
|
# write_only=True
|
||||||
|
#)
|
||||||
|
owner = serializers.PrimaryKeyRelatedField(read_only=True)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Team
|
model = Team
|
||||||
fields = ['zekken_number', 'team_name', 'password', 'owner']
|
fields = ['id','zekken_number', 'team_name', 'category', 'owner']
|
||||||
|
read_only_fields = ['id', 'owner', 'zekken_number']
|
||||||
|
|
||||||
|
def to_representation(self, instance):
|
||||||
|
ret = super().to_representation(instance)
|
||||||
|
ret['category'] = {
|
||||||
|
'id': instance.category.id,
|
||||||
|
'category_name': instance.category.category_name,
|
||||||
|
'category_number': instance.category.category_number
|
||||||
|
}
|
||||||
|
ret['owner'] = CustomUserSerializer(instance.owner).data
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def validate_category(self, value):
|
||||||
|
if not NewCategory.objects.filter(id=value.id).exists():
|
||||||
|
raise serializers.ValidationError("Invalid category ID.")
|
||||||
|
return value
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
category = validated_data.pop('category')
|
||||||
|
team = Team.objects.create(category=category, **validated_data)
|
||||||
|
return team
|
||||||
|
|
||||||
|
#logger.debug(f"Creating team with data: {validated_data}")
|
||||||
|
#validated_data['owner'] = self.context['request'].user
|
||||||
|
#return super().create(validated_data)
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
if 'category' in validated_data:
|
||||||
|
instance.category = validated_data.pop('category')
|
||||||
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
class CategorySerializer(serializers.ModelSerializer):
|
class CategorySerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -210,29 +272,60 @@ class CategorySerializer(serializers.ModelSerializer):
|
|||||||
fields = ['category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']
|
fields = ['category_name', 'category_number', 'duration', 'num_of_member', 'family', 'female']
|
||||||
|
|
||||||
class EntrySerializer(serializers.ModelSerializer):
|
class EntrySerializer(serializers.ModelSerializer):
|
||||||
|
team = serializers.PrimaryKeyRelatedField(queryset=Team.objects.all())
|
||||||
|
event = serializers.PrimaryKeyRelatedField(queryset=NewEvent.objects.all())
|
||||||
|
category = serializers.PrimaryKeyRelatedField(queryset=NewCategory.objects.all())
|
||||||
|
owner = serializers.PrimaryKeyRelatedField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Entry
|
model = Entry
|
||||||
fields = ['team', 'event', 'category', 'date']
|
fields = ['id','team', 'event', 'category', 'date','owner']
|
||||||
|
|
||||||
class MemberSerializer(serializers.ModelSerializer):
|
def validate_team(self, value):
|
||||||
class Meta:
|
if not value.members.exists():
|
||||||
model = Member
|
raise serializers.ValidationError("チームにメンバーが登録されていません。")
|
||||||
fields = ['team', 'user']
|
return value
|
||||||
|
|
||||||
class TempUserSerializer(serializers.ModelSerializer):
|
def to_representation(self, instance):
|
||||||
class Meta:
|
ret = super().to_representation(instance)
|
||||||
model = TempUser
|
ret['team'] = instance.team.team_name
|
||||||
fields = ['email', 'password', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'firstname', 'lastname', 'date_of_birth', 'female', 'verification_code', 'created_at', 'expires_at']
|
ret['event'] = instance.event.event_name
|
||||||
|
ret['category'] = instance.category.category_name
|
||||||
|
ret['owner'] = instance.owner.email
|
||||||
|
return ret
|
||||||
|
|
||||||
class CustomUserSerializer(serializers.ModelSerializer):
|
class CustomUserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomUser
|
model = CustomUser
|
||||||
fields = ['email', 'is_staff', 'is_active', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'firstname', 'lastname', 'date_of_birth', 'female']
|
#fields = ['email', 'is_staff', 'is_active', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'firstname', 'lastname', 'date_of_birth', 'female']
|
||||||
|
fields = ['id','email', 'firstname', 'lastname', 'date_of_birth', 'female']
|
||||||
|
read_only_fields = ['email']
|
||||||
|
|
||||||
|
class TeamDetailSerializer(serializers.ModelSerializer):
|
||||||
|
category = NewCategorySerializer(read_only=True)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Team
|
||||||
|
fields = ['id', 'zekken_number', 'team_name', 'category']
|
||||||
|
|
||||||
class UserSerializer(serializers.ModelSerializer):
|
class UserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomUser
|
model = CustomUser
|
||||||
fields = ['email', 'firstname', 'lastname', 'date_of_birth', 'female', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group']
|
fields = ['id','email', 'firstname', 'lastname', 'date_of_birth', 'female', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group']
|
||||||
|
read_only_fields = ('id', 'email')
|
||||||
|
|
||||||
|
class UserUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = CustomUser
|
||||||
|
fields = ['firstname', 'lastname', 'date_of_birth', 'female']
|
||||||
|
extra_kwargs = {'email': {'read_only': True}}
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
for attr, value in validated_data.items():
|
||||||
|
setattr(instance, attr, value)
|
||||||
|
instance.save()
|
||||||
|
return instance
|
||||||
|
|
||||||
|
|
||||||
class MemberWithUserSerializer(serializers.ModelSerializer):
|
class MemberWithUserSerializer(serializers.ModelSerializer):
|
||||||
user = UserSerializer(read_only=True)
|
user = UserSerializer(read_only=True)
|
||||||
@ -240,3 +333,149 @@ class MemberWithUserSerializer(serializers.ModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Member
|
model = Member
|
||||||
fields = ['user', 'team']
|
fields = ['user', 'team']
|
||||||
|
|
||||||
|
class MemberSerializer(serializers.ModelSerializer):
|
||||||
|
user = CustomUserSerializer()
|
||||||
|
team = TeamDetailSerializer(read_only=True)
|
||||||
|
|
||||||
|
#email = serializers.EmailField(write_only=True, required=False)
|
||||||
|
#firstname = serializers.CharField(write_only=True, required=False)
|
||||||
|
#lastname = serializers.CharField(write_only=True, required=False)
|
||||||
|
#date_of_birth = serializers.DateField(write_only=True, required=False)
|
||||||
|
#female = serializers.BooleanField(write_only=True, required=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Member
|
||||||
|
fields = ['id','user','team'] # ,'email','firstname','lastname','date_of_birth','female']
|
||||||
|
#read_only_fields = ['id', 'team']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
team = validated_data['team']
|
||||||
|
email = validated_data.get('email')
|
||||||
|
|
||||||
|
if email:
|
||||||
|
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.is_active = False
|
||||||
|
user.activation_token = str(uuid.uuid4())
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
activation_link = self.context['request'].build_absolute_uri(
|
||||||
|
reverse('user-activation', kwargs={'activation_token': user.activation_token})
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
send_activation_email(user, activation_link)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"アクティベーションメールの送信中にエラーが発生しました: {str(e)}")
|
||||||
|
# メール送信に失敗しても、ユーザー作成は続行します
|
||||||
|
|
||||||
|
else:
|
||||||
|
dummy_email = f"dummy_{uuid.uuid4()}@example.com"
|
||||||
|
user = CustomUser.objects.create(
|
||||||
|
email=dummy_email,
|
||||||
|
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),
|
||||||
|
is_active=True
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
member = Member.objects.create(user=user, team=team)
|
||||||
|
except IntegrityError:
|
||||||
|
# ユーザーがすでにチームのメンバーの場合
|
||||||
|
raise serializers.ValidationError("このユーザーは既にチームのメンバーです。")
|
||||||
|
|
||||||
|
return member
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
user_data = validated_data.pop('user', {})
|
||||||
|
user = instance.user
|
||||||
|
|
||||||
|
if user.email.startswith('dummy_'): # dummy_ で始まるメールアドレスの場合のみ更新
|
||||||
|
for attr, value in user_data.items():
|
||||||
|
setattr(user, attr, value)
|
||||||
|
user.save()
|
||||||
|
else:
|
||||||
|
raise serializers.ValidationError("このユーザーの情報は更新できません。")
|
||||||
|
|
||||||
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class EntryMemberSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = EntryMember
|
||||||
|
fields = ['id', 'entry', 'member', 'is_temporary']
|
||||||
|
|
||||||
|
|
||||||
|
class TempUserSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = TempUser
|
||||||
|
fields = ['id','email', 'password', 'is_rogaining', 'zekken_number', 'event_code', 'team_name', 'group', 'firstname', 'lastname', 'date_of_birth', 'female', 'verification_code', 'created_at', 'expires_at']
|
||||||
|
|
||||||
|
class EntryCreationSerializer(serializers.Serializer):
|
||||||
|
owner_email = serializers.EmailField()
|
||||||
|
event_name = serializers.CharField()
|
||||||
|
category_name = serializers.CharField()
|
||||||
|
team_name = serializers.CharField()
|
||||||
|
zekken_number = serializers.CharField()
|
||||||
|
date = serializers.DateField()
|
||||||
|
members = serializers.ListField(child=serializers.DictField())
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
owner = CustomUser.objects.get(email=validated_data['owner_email'])
|
||||||
|
event = NewEvent2.objects.get(event_name=validated_data['event_name'])
|
||||||
|
category = NewCategory.objects.get(category_name=validated_data['category_name'])
|
||||||
|
|
||||||
|
# Create or get team
|
||||||
|
team, _ = Team.objects.get_or_create(
|
||||||
|
zekken_number=validated_data['zekken_number'],
|
||||||
|
category=category,
|
||||||
|
defaults={'team_name': validated_data['team_name'], 'owner': owner}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create or update entry
|
||||||
|
entry, _ = Entry.objects.update_or_create(
|
||||||
|
owner=owner,
|
||||||
|
team=team,
|
||||||
|
event=event,
|
||||||
|
date=validated_data['date'],
|
||||||
|
defaults={'category': category}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Process members
|
||||||
|
for member_data in validated_data['members']:
|
||||||
|
user, created = CustomUser.objects.get_or_create(
|
||||||
|
email=member_data.get('email'),
|
||||||
|
defaults={
|
||||||
|
'firstname': member_data['firstname'],
|
||||||
|
'lastname': member_data['lastname'],
|
||||||
|
'date_of_birth': member_data['date_of_birth']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if created:
|
||||||
|
TempUser.objects.create(
|
||||||
|
email=user.email,
|
||||||
|
firstname=user.firstname,
|
||||||
|
lastname=user.lastname,
|
||||||
|
date_of_birth=user.date_of_birth
|
||||||
|
)
|
||||||
|
# Send invitation email here
|
||||||
|
|
||||||
|
member, _ = NewMember.objects.get_or_create(
|
||||||
|
user=user,
|
||||||
|
team=team,
|
||||||
|
defaults={'is_temporary': created}
|
||||||
|
)
|
||||||
|
|
||||||
|
EntryMember.objects.get_or_create(entry=entry, member=member)
|
||||||
|
|
||||||
|
return entry
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
16
rog/templates/email/activation_email.txt
Normal file
16
rog/templates/email/activation_email.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
件名: アカウントのアクティベーション
|
||||||
|
{name} 様
|
||||||
|
|
||||||
|
この度は、サービスにご登録いただき、ありがとうございます。
|
||||||
|
以下のリンクをクリックしてアカウントをアクティベートしてください:
|
||||||
|
|
||||||
|
{activation_link}
|
||||||
|
|
||||||
|
また、アプリをダウンロードしてください:
|
||||||
|
|
||||||
|
{app_download_link}
|
||||||
|
|
||||||
|
このメールに心当たりがない場合は、お手数ですが破棄してください。
|
||||||
|
よろしくお願いいたします。
|
||||||
|
|
||||||
|
{service_name} チーム
|
||||||
16
rog/templates/email/activation_friend_email.txt
Normal file
16
rog/templates/email/activation_friend_email.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
件名: アカウントのアクティベーション
|
||||||
|
|
||||||
|
{name} 様
|
||||||
|
|
||||||
|
この度は、サービスにご登録いただき、ありがとうございます。
|
||||||
|
|
||||||
|
以下のリンクをクリックしてアカウントをアクティベートしてください:
|
||||||
|
{activation_link}
|
||||||
|
|
||||||
|
また、アプリをダウンロードしてください:
|
||||||
|
{app_download_link}
|
||||||
|
|
||||||
|
このメールに心当たりがない場合は、お手数ですが破棄してください。
|
||||||
|
よろしくお願いいたします。
|
||||||
|
|
||||||
|
{service_name} チーム
|
||||||
22
rog/urls.py
22
rog/urls.py
@ -1,12 +1,13 @@
|
|||||||
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,CategoryListView, MemberUserDetailView, TeamMembersWithUserView
|
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
|
||||||
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
|
||||||
|
|
||||||
from .views import TestActionViewSet
|
from .views import TestActionViewSet
|
||||||
|
|
||||||
|
from .views import OwnerEntriesView, OwnerTeamsView, OwnerMembersView
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
|
|
||||||
@ -26,9 +27,14 @@ router.register(prefix='checkinimage', viewset=CheckinImageViewSet, basename='ch
|
|||||||
# /api/entries/ - エントリーの一覧取得と作成
|
# /api/entries/ - エントリーの一覧取得と作成
|
||||||
# /api/entries/<pk>/ - 特定のエントリーの取得、更新、削除
|
# /api/entries/<pk>/ - 特定のエントリーの取得、更新、削除
|
||||||
#
|
#
|
||||||
router.register(r'teams', TeamViewSet)
|
#router.register(r'teams', TeamViewSet)
|
||||||
router.register(r'members', MemberViewSet)
|
#router.register(r'members', MemberViewSet)
|
||||||
router.register(r'entries', EntryViewSet)
|
#router.register(r'entries', EntryViewSet)
|
||||||
|
|
||||||
|
router.register(r'entry', EntryViewSet, basename='entry')
|
||||||
|
router.register(r'teams', TeamViewSet, basename='team')
|
||||||
|
router.register(r'members', MemberViewSet, basename='member')
|
||||||
|
|
||||||
|
|
||||||
# Akira 追加
|
# Akira 追加
|
||||||
# GET /api/members/<member_id>/user/: 特定のメンバーのユーザー情報を取得
|
# GET /api/members/<member_id>/user/: 特定のメンバーのユーザー情報を取得
|
||||||
@ -69,9 +75,13 @@ urlpatterns += [
|
|||||||
# path('goal-image/', GoalImageViewSet.as_view(), name='goal-image')
|
# path('goal-image/', GoalImageViewSet.as_view(), name='goal-image')
|
||||||
path('register/', RegisterView.as_view(), name='register'),
|
path('register/', RegisterView.as_view(), name='register'),
|
||||||
path('verify-email/<uuid:verification_code>/', VerifyEmailView.as_view(), name='verify-email'),
|
path('verify-email/<uuid:verification_code>/', VerifyEmailView.as_view(), name='verify-email'),
|
||||||
path('categories/', CategoryListView.as_view(), name='category-list'),
|
path('categories/', NewCategoryListView.as_view(), name='category-list'),
|
||||||
path('new-events/', NewEventListView.as_view(), name='new-event-list'),
|
path('new-events/', NewEvent2ListView.as_view(), name='new-event-list'),
|
||||||
path('members/<int:pk>/user/', MemberUserDetailView.as_view(), name='member-user-detail'),
|
path('members/<int:pk>/user/', MemberUserDetailView.as_view(), name='member-user-detail'),
|
||||||
path('teams/<int:team_id>/members-with-user/', TeamMembersWithUserView.as_view(), name='team-members-with-user'),
|
path('teams/<int:team_id>/members-with-user/', TeamMembersWithUserView.as_view(), name='team-members-with-user'),
|
||||||
|
|
||||||
|
path('teams/<int:team_id>/members/', MemberViewSet.as_view({'get': 'list', 'post': 'create'}), name='team-members'),
|
||||||
|
path('teams/<int:team_id>/members/<int:pk>/', MemberViewSet.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}), name='team-member-detail'),
|
||||||
|
path('activate/<str:activation_token>/', UserActivationView.as_view(), name='user-activation'),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|||||||
34
rog/utils.py
Normal file
34
rog/utils.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import os
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
from django.conf import settings
|
||||||
|
import logging
|
||||||
|
from django.core.mail import send_mail
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def load_email_template(template_name, context):
|
||||||
|
template_path = os.path.join('email', template_name)
|
||||||
|
email_content = render_to_string(template_path, context)
|
||||||
|
|
||||||
|
# 件名と本文を分離
|
||||||
|
subject, _, body = email_content.partition('\n\n')
|
||||||
|
subject = subject.replace('件名: ', '').strip()
|
||||||
|
|
||||||
|
return subject, body
|
||||||
|
|
||||||
|
def send_activation_email(user, activation_link):
|
||||||
|
context = {
|
||||||
|
'name': user.firstname or user.email,
|
||||||
|
'activation_link': activation_link,
|
||||||
|
'app_download_link': settings.APP_DOWNLOAD_LINK,
|
||||||
|
'service_name': settings.SERVICE_NAME,
|
||||||
|
}
|
||||||
|
|
||||||
|
subject, body = load_email_template('activation_email.txt', context)
|
||||||
|
|
||||||
|
try:
|
||||||
|
send_mail(subject, body, settings.DEFAULT_FROM_EMAIL, [user.email], fail_silently=False)
|
||||||
|
logger.info(f"アクティベーションメールを送信しました。 受信者: {user.email}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"アクティベーションメールの送信に失敗しました。 受信者: {user.email}, エラー: {str(e)}")
|
||||||
|
raise # エラーを再度発生させて、呼び出し元で処理できるようにします
|
||||||
278
rog/views.py
278
rog/views.py
@ -1,12 +1,28 @@
|
|||||||
|
from rest_framework import serializers
|
||||||
|
from django.db import IntegrityError
|
||||||
|
from django.urls import reverse
|
||||||
|
from .utils import send_activation_email
|
||||||
|
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
|
||||||
|
from .permissions import IsTeamOwner
|
||||||
|
|
||||||
from curses.ascii import NUL
|
from curses.ascii import NUL
|
||||||
from django.core.serializers import serialize
|
from django.core.serializers import serialize
|
||||||
from .models import GoalImages, Location, Location_line, Location_polygon, JpnAdminMainPerf, Useractions, GifuAreas, RogUser, CustomUser, UserTracks, GoalImages, CheckinImages, NewEvent, Team, Category, Entry, Member, TempUser
|
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 rest_framework import viewsets
|
||||||
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, MemberWithUserSerializer
|
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, MemberWithUserSerializer
|
||||||
from knox.models import AuthToken
|
from knox.models import AuthToken
|
||||||
|
|
||||||
from rest_framework import viewsets, generics, status
|
from rest_framework import viewsets, generics, status
|
||||||
from rest_framework.decorators import action
|
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.parsers import JSONParser, MultiPartParser
|
from rest_framework.parsers import JSONParser, MultiPartParser
|
||||||
from .serializers import LocationSerializer
|
from .serializers import LocationSerializer
|
||||||
@ -14,7 +30,7 @@ from django.http import JsonResponse
|
|||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from django.contrib.gis.db.models import Extent, Union
|
from django.contrib.gis.db.models import Extent, Union
|
||||||
|
|
||||||
from .serializers import TestSerialiser,NewEventSerializer, TeamSerializer, CategorySerializer, EntrySerializer, MemberSerializer, TempUserSerializer, CustomUserSerializer
|
from .serializers import TestSerialiser,NewEventSerializer,NewEvent2Serializer, TeamSerializer, NewCategorySerializer,CategorySerializer, EntrySerializer, MemberSerializer, TempUserSerializer, CustomUserSerializer,EntryMemberSerializer,EntryCreationSerializer
|
||||||
from .models import TestModel
|
from .models import TestModel
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
@ -27,13 +43,17 @@ from rest_framework.decorators import api_view
|
|||||||
from rest_framework.decorators import api_view, permission_classes
|
from rest_framework.decorators import api_view, permission_classes
|
||||||
from rest_framework.parsers import JSONParser, MultiPartParser
|
from rest_framework.parsers import JSONParser, MultiPartParser
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
import uuid
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from .permissions import IsMemberOrTeamOwner
|
from .permissions import IsMemberOrTeamOwner
|
||||||
|
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_str
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class LocationViewSet(viewsets.ModelViewSet):
|
class LocationViewSet(viewsets.ModelViewSet):
|
||||||
queryset=Location.objects.all()
|
queryset=Location.objects.all()
|
||||||
serializer_class=LocationSerializer
|
serializer_class=LocationSerializer
|
||||||
@ -288,6 +308,25 @@ class LoginAPI(generics.GenericAPIView):
|
|||||||
"token": AuthToken.objects.create(user)[1]
|
"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)
|
||||||
|
|
||||||
class UserAPI(generics.RetrieveAPIView):
|
class UserAPI(generics.RetrieveAPIView):
|
||||||
permission_classes = [permissions.IsAuthenticated,]
|
permission_classes = [permissions.IsAuthenticated,]
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
@ -509,6 +548,17 @@ def CustomAreaNames(request):
|
|||||||
return JsonResponse(serializer.data, safe=False)
|
return JsonResponse(serializer.data, safe=False)
|
||||||
|
|
||||||
|
|
||||||
|
class UserActivationView(APIView):
|
||||||
|
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):
|
class ChangePasswordView(generics.UpdateAPIView):
|
||||||
"""
|
"""
|
||||||
An endpoint for changing password.
|
An endpoint for changing password.
|
||||||
@ -562,32 +612,96 @@ class RegistrationView(APIView):
|
|||||||
|
|
||||||
# Akira
|
# Akira
|
||||||
|
|
||||||
@method_decorator(csrf_exempt, name='dispatch')
|
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):
|
class NewEventViewSet(viewsets.ModelViewSet):
|
||||||
queryset = NewEvent.objects.all()
|
queryset = NewEvent.objects.all()
|
||||||
serializer_class = NewEventSerializer
|
serializer_class = NewEventSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
@method_decorator(csrf_exempt, name='dispatch')
|
|
||||||
class NewEventListView(generics.ListAPIView):
|
class NewEventListView(generics.ListAPIView):
|
||||||
queryset = NewEvent.objects.all()
|
queryset = NewEvent.objects.all()
|
||||||
serializer_class = NewEventSerializer
|
serializer_class = NewEventSerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
class TeamViewSet(viewsets.ModelViewSet):
|
class TeamViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Team.objects.all()
|
|
||||||
serializer_class = TeamSerializer
|
serializer_class = TeamSerializer
|
||||||
permission_classes = [permissions.IsAuthenticated]
|
permission_classes = [permissions.IsAuthenticated, IsTeamOwner]
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Team.objects.filter(owner=self.request.user)
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(owner=self.request.user)
|
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):
|
class CategoryViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Category.objects.all()
|
queryset = Category.objects.all()
|
||||||
serializer_class = CategorySerializer
|
serializer_class = CategorySerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
@method_decorator(csrf_exempt, name='dispatch')
|
|
||||||
class CategoryListView(generics.ListAPIView):
|
class CategoryListView(generics.ListAPIView):
|
||||||
queryset = Category.objects.all()
|
queryset = Category.objects.all()
|
||||||
serializer_class = CategorySerializer
|
serializer_class = CategorySerializer
|
||||||
@ -611,16 +725,148 @@ class EntryViewSet(viewsets.ModelViewSet):
|
|||||||
serializer_class = EntrySerializer
|
serializer_class = EntrySerializer
|
||||||
permission_classes = [permissions.IsAuthenticated]
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
#def perform_create(self, serializer):
|
||||||
team = Team.objects.get(owner=self.request.user)
|
# team = Team.objects.get(owner=self.request.user)
|
||||||
serializer.save(team=team)
|
# serializer.save(team=team)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
user = self.request.user
|
||||||
|
# ユーザーが所属するチームのIDを取得
|
||||||
|
team_ids = Member.objects.filter(user=user).values_list('team_id', flat=True)
|
||||||
|
# そのチームに関連するエントリーを取得
|
||||||
|
return Entry.objects.filter(team__id__in=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": str(e)}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
#except ValidationError as e:
|
||||||
|
# return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
serializer.save(owner=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)
|
||||||
|
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)
|
||||||
|
|
||||||
class MemberViewSet(viewsets.ModelViewSet):
|
class MemberViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Member.objects.all()
|
serializer_class = MemberSerializer
|
||||||
|
permission_classes = [permissions.IsAuthenticated,IsTeamOwner]
|
||||||
|
|
||||||
|
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)
|
||||||
|
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 perform_create(self, serializer):
|
||||||
|
team = Team.objects.get(id=self.kwargs['team_id'])
|
||||||
|
serializer.save(team=team)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
if not instance.user.email.startswith('dummy_'):
|
||||||
|
return Response({"error": "このユーザーの情報は更新できません。"}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
|
self.perform_update(serializer)
|
||||||
|
|
||||||
|
if getattr(instance, '_prefetched_objects_cache', None):
|
||||||
|
instance._prefetched_objects_cache = {}
|
||||||
|
|
||||||
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
def perform_update(self, serializer):
|
||||||
|
serializer.save()
|
||||||
|
|
||||||
|
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
|
serializer_class = MemberSerializer
|
||||||
permission_classes = [permissions.IsAuthenticated]
|
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):
|
class TempUserViewSet(viewsets.ModelViewSet):
|
||||||
queryset = TempUser.objects.all()
|
queryset = TempUser.objects.all()
|
||||||
@ -639,9 +885,6 @@ class CustomUserViewSet(viewsets.ModelViewSet):
|
|||||||
return CustomUser.objects.all()
|
return CustomUser.objects.all()
|
||||||
return CustomUser.objects.filter(id=user.id)
|
return CustomUser.objects.filter(id=user.id)
|
||||||
|
|
||||||
# 追加の機能として、チームメンバーを取得するビュー
|
|
||||||
from rest_framework.decorators import action
|
|
||||||
from rest_framework.response import Response
|
|
||||||
|
|
||||||
class TeamMembersView(generics.ListAPIView):
|
class TeamMembersView(generics.ListAPIView):
|
||||||
serializer_class = MemberSerializer
|
serializer_class = MemberSerializer
|
||||||
@ -738,4 +981,3 @@ class TeamMembersWithUserView(generics.ListAPIView):
|
|||||||
team_id = self.kwargs['team_id']
|
team_id = self.kwargs['team_id']
|
||||||
return Member.objects.filter(team_id=team_id).select_related('user', 'team')
|
return Member.objects.filter(team_id=team_id).select_related('user', 'team')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user