1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-02-13 21:41:19 +00:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Yohann D'ANELLO
bf6f87ee89
Indicate the maximum amount of teams in a tournament 2020-12-31 12:26:49 +01:00
Yohann D'ANELLO
52f0d442cd
Better date render 2020-12-31 12:23:09 +01:00
Yohann D'ANELLO
4e29b4830a
Create tournaments 2020-12-31 12:13:42 +01:00
15 changed files with 171 additions and 104 deletions

View File

@ -3,11 +3,13 @@
import re import re
from bootstrap_datepicker_plus import DatePickerInput, DateTimePickerInput
from django import forms from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils import formats
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import Participation, Team from .models import Participation, Team, Tournament
class TeamForm(forms.ModelForm): class TeamForm(forms.ModelForm):
@ -85,3 +87,25 @@ class ValidateParticipationForm(forms.Form):
label=_("Message to address to the team:"), label=_("Message to address to the team:"),
widget=forms.Textarea(), widget=forms.Textarea(),
) )
class TournamentForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["date_start"].widget = DatePickerInput(
format=formats.get_format_lazy(format_type="DATE_INPUT_FORMATS", use_l10n=True)[0])
self.fields["date_end"].widget = DatePickerInput(
format=formats.get_format_lazy(format_type="DATE_INPUT_FORMATS", use_l10n=True)[0])
self.fields["inscription_limit"].widget = DateTimePickerInput(
format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0])
self.fields["solution_limit"].widget = DateTimePickerInput(
format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0])
self.fields["syntheses_first_phase_limit"].widget = DateTimePickerInput(
format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0])
self.fields["syntheses_second_phase_limit"].widget = DateTimePickerInput(
format=formats.get_format_lazy(format_type="DATETIME_INPUT_FORMATS", use_l10n=True)[0])
class Meta:
model = Tournament
fields = '__all__'

View File

@ -1,4 +1,4 @@
# Generated by Django 3.1.4 on 2020-12-28 17:16 # Generated by Django 3.0.11 on 2020-12-30 12:02
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
@ -79,7 +79,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True, verbose_name='name')), ('name', models.CharField(max_length=255, unique=True, verbose_name='name')),
('date_start', models.DateField(default=django.utils.timezone.now, verbose_name='start')), ('date_start', models.DateField(default=django.utils.timezone.now, verbose_name='start')),
('date_end', models.DateField(default=django.utils.timezone.now, verbose_name='start')), ('date_end', models.DateField(default=django.utils.timezone.now, verbose_name='end')),
('inscription_limit', models.DateTimeField(default=django.utils.timezone.now, verbose_name='limit date for registrations')), ('inscription_limit', models.DateTimeField(default=django.utils.timezone.now, verbose_name='limit date for registrations')),
('solution_limit', models.DateTimeField(default=django.utils.timezone.now, verbose_name='limit date to upload solutions')), ('solution_limit', models.DateTimeField(default=django.utils.timezone.now, verbose_name='limit date to upload solutions')),
('syntheses_first_phase_limit', models.DateTimeField(default=django.utils.timezone.now, verbose_name='limit date to upload the syntheses for the first phase')), ('syntheses_first_phase_limit', models.DateTimeField(default=django.utils.timezone.now, verbose_name='limit date to upload the syntheses for the first phase')),

View File

@ -1,5 +1,6 @@
# Generated by Django 3.1.4 on 2020-12-28 17:16 # Generated by Django 3.0.11 on 2020-12-30 12:02
import address.models
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -9,8 +10,9 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('participation', '0001_initial'),
('registration', '0001_initial'), ('registration', '0001_initial'),
('address', '0003_auto_20200830_1851'),
('participation', '0001_initial'),
] ]
operations = [ operations = [
@ -19,6 +21,11 @@ class Migration(migrations.Migration):
name='organizers', name='organizers',
field=models.ManyToManyField(related_name='organized_tournaments', to='registration.VolunteerRegistration', verbose_name='organizers'), field=models.ManyToManyField(related_name='organized_tournaments', to='registration.VolunteerRegistration', verbose_name='organizers'),
), ),
migrations.AddField(
model_name='tournament',
name='place',
field=address.models.AddressField(on_delete=django.db.models.deletion.CASCADE, to='address.Address', verbose_name='place'),
),
migrations.AddIndex( migrations.AddIndex(
model_name='team', model_name='team',
index=models.Index(fields=['trigram'], name='participati_trigram_239255_idx'), index=models.Index(fields=['trigram'], name='participati_trigram_239255_idx'),
@ -26,17 +33,17 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='synthesis', model_name='synthesis',
name='participation', name='participation',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='participation.participation', verbose_name='participation'), field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='participation.Participation', verbose_name='participation'),
), ),
migrations.AddField( migrations.AddField(
model_name='synthesis', model_name='synthesis',
name='pool', name='pool',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='syntheses', to='participation.pool', verbose_name='pool'), field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='syntheses', to='participation.Pool', verbose_name='pool'),
), ),
migrations.AddField( migrations.AddField(
model_name='solution', model_name='solution',
name='participation', name='participation',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='solutions', to='participation.participation', verbose_name='participation'), field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='solutions', to='participation.Participation', verbose_name='participation'),
), ),
migrations.AddField( migrations.AddField(
model_name='pool', model_name='pool',
@ -51,17 +58,17 @@ class Migration(migrations.Migration):
migrations.AddField( migrations.AddField(
model_name='pool', model_name='pool',
name='tournament', name='tournament',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pools', to='participation.tournament', verbose_name='tournament'), field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pools', to='participation.Tournament', verbose_name='tournament'),
), ),
migrations.AddField( migrations.AddField(
model_name='participation', model_name='participation',
name='team', name='team',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='participation.team', verbose_name='team'), field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='participation.Team', verbose_name='team'),
), ),
migrations.AddField( migrations.AddField(
model_name='participation', model_name='participation',
name='tournament', name='tournament',
field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='participation.tournament', verbose_name='tournament'), field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='participation.Tournament', verbose_name='tournament'),
), ),
migrations.AddIndex( migrations.AddIndex(
model_name='tournament', model_name='tournament',

View File

@ -0,0 +1,18 @@
# Generated by Django 3.0.11 on 2020-12-31 11:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('participation', '0002_auto_20201230_1302'),
]
operations = [
migrations.AddField(
model_name='tournament',
name='max_teams',
field=models.PositiveSmallIntegerField(default=9, verbose_name='max team count'),
),
]

View File

@ -3,6 +3,7 @@
import os import os
from address.models import AddressField
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.db import models from django.db import models
from django.db.models import Index from django.db.models import Index
@ -133,6 +134,15 @@ class Tournament(models.Model):
default=timezone.now, default=timezone.now,
) )
place = AddressField(
verbose_name=_("place"),
)
max_teams = models.PositiveSmallIntegerField(
verbose_name=_("max team count"),
default=9,
)
inscription_limit = models.DateTimeField( inscription_limit = models.DateTimeField(
verbose_name=_("limit date for registrations"), verbose_name=_("limit date for registrations"),
default=timezone.now, default=timezone.now,
@ -193,6 +203,9 @@ class Tournament(models.Model):
return Synthesis.objects.filter(final_solution=True) return Synthesis.objects.filter(final_solution=True)
return Synthesis.objects.filter(participation__tournament=self) return Synthesis.objects.filter(participation__tournament=self)
def get_absolute_url(self):
return reverse_lazy("participation:tournament_detail", args=(self.pk,))
def __str__(self): def __str__(self):
return repr(self) return repr(self)

View File

@ -1,5 +1,6 @@
# Copyright (C) 2020 by Animath # Copyright (C) 2020 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from django.utils import formats
from django.utils.text import format_lazy from django.utils.text import format_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import django_tables2 as tables import django_tables2 as tables
@ -57,8 +58,14 @@ class ParticipationTable(tables.Table):
class TournamentTable(tables.Table): class TournamentTable(tables.Table):
name = tables.LinkColumn()
date = tables.Column(_("date").capitalize, accessor="id")
def render_date(self, record): def render_date(self, record):
return format_lazy(_("From {start} to {end}"), start=record.start, end=record.end) return format_lazy(_("From {start} to {end}"),
start=formats.date_format(record.date_start, format="SHORT_DATE_FORMAT", use_l10n=True),
end=formats.date_format(record.date_end, format="SHORT_DATE_FORMAT", use_l10n=True))
class Meta: class Meta:
attrs = { attrs = {

View File

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% load crispy_forms_filters i18n %}
{% block content %}
<form method="post">
<div id="form-content">
{% csrf_token %}
{{ form|crispy }}
</div>
<button class="btn btn-success" type="submit">{% trans "Create" %}</button>
</form>
{% endblock content %}

View File

@ -10,7 +10,7 @@
<div id="form-content"> <div id="form-content">
{% render_table table %} {% render_table table %}
{% if user.registration.is_admin %} {% if user.registration.is_admin %}
<a class="btn btn-block btn-success" href="#">{% trans "Add tournament" %}</a> <a class="btn btn-block btn-success" href="{% url "participation:tournament_create" %}">{% trans "Add tournament" %}</a>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -6,7 +6,8 @@ from django.views.generic import TemplateView
from .views import CreateTeamView, JoinTeamView, \ from .views import CreateTeamView, JoinTeamView, \
MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, TeamAuthorizationsView, \ MyParticipationDetailView, MyTeamDetailView, ParticipationDetailView, TeamAuthorizationsView, \
TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, TournamentListView TeamDetailView, TeamLeaveView, TeamListView, TeamUpdateView, TournamentCreateView, TournamentDetailView, \
TournamentListView, TournamentUpdateView
app_name = "participation" app_name = "participation"
@ -23,5 +24,8 @@ urlpatterns = [
path("detail/", MyParticipationDetailView.as_view(), name="my_participation_detail"), path("detail/", MyParticipationDetailView.as_view(), name="my_participation_detail"),
path("detail/<int:pk>/", ParticipationDetailView.as_view(), name="participation_detail"), path("detail/<int:pk>/", ParticipationDetailView.as_view(), name="participation_detail"),
path("tournament/", TournamentListView.as_view(), name="tournament_list"), path("tournament/", TournamentListView.as_view(), name="tournament_list"),
path("tournament/create/", TournamentCreateView.as_view(), name="tournament_create"),
path("tournament/<int:pk>/", TournamentDetailView.as_view(), name="tournament_detail"),
path("tournament/<int:pk>/update/", TournamentUpdateView.as_view(), name="tournament_update"),
path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat") path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat")
] ]

View File

@ -23,7 +23,8 @@ from tfjm.lists import get_sympa_client
from tfjm.matrix import Matrix from tfjm.matrix import Matrix
from tfjm.views import AdminMixin from tfjm.views import AdminMixin
from .forms import JoinTeamForm, ParticipationForm, RequestValidationForm, TeamForm, ValidateParticipationForm from .forms import JoinTeamForm, ParticipationForm, RequestValidationForm, TeamForm, ValidateParticipationForm, \
TournamentForm
from .models import Participation, Team, Tournament from .models import Participation, Team, Tournament
from .tables import TeamTable, TournamentTable from .tables import TeamTable, TournamentTable
@ -73,9 +74,6 @@ class CreateTeamView(LoginRequiredMixin, CreateView):
f"@{user.registration.matrix_username}:tfjm.org") f"@{user.registration.matrix_username}:tfjm.org")
return ret return ret
def get_success_url(self):
return reverse_lazy("participation:team_detail", args=(self.object.pk,))
class JoinTeamView(LoginRequiredMixin, FormView): class JoinTeamView(LoginRequiredMixin, FormView):
""" """
@ -293,9 +291,6 @@ class TeamUpdateView(LoginRequiredMixin, UpdateView):
participation_form.save() participation_form.save()
return super().form_valid(form) return super().form_valid(form)
def get_success_url(self):
return reverse_lazy("participation:team_detail", args=(self.object.pk,))
class TeamAuthorizationsView(LoginRequiredMixin, DetailView): class TeamAuthorizationsView(LoginRequiredMixin, DetailView):
""" """
@ -404,5 +399,34 @@ class ParticipationDetailView(LoginRequiredMixin, DetailView):
class TournamentListView(SingleTableView): class TournamentListView(SingleTableView):
"""
Display the list of all tournaments.
"""
model = Tournament model = Tournament
table_class = TournamentTable table_class = TournamentTable
class TournamentCreateView(AdminMixin, CreateView):
"""
Create a new tournament.
"""
model = Tournament
form_class = TournamentForm
def get_success_url(self):
return reverse_lazy("participation:tournament_detail", args=(self.object.pk,))
class TournamentUpdateView(AdminMixin, UpdateView):
"""
Update tournament detail.
"""
model = Tournament
form_class = TournamentForm
class TournamentDetailView(DetailView):
"""
Display tournament detail.
"""
model = Tournament

View File

@ -1,8 +1,11 @@
# Generated by Django 3.1.4 on 2020-12-28 17:16 # Generated by Django 3.0.11 on 2020-12-30 12:02
import address.models
import datetime
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import phonenumber_field.modelfields
import registration.models import registration.models
@ -11,9 +14,10 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('participation', '0001_initial'),
('contenttypes', '0002_remove_content_type_name'), ('contenttypes', '0002_remove_content_type_name'),
('address', '0003_auto_20200830_1851'),
('participation', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
] ]
operations = [ operations = [
@ -23,7 +27,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('give_contact_to_animath', models.BooleanField(default=False, verbose_name='Grant Animath to contact me in the future about other actions')), ('give_contact_to_animath', models.BooleanField(default=False, verbose_name='Grant Animath to contact me in the future about other actions')),
('email_confirmed', models.BooleanField(default=False, verbose_name='email confirmed')), ('email_confirmed', models.BooleanField(default=False, verbose_name='email confirmed')),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_registration.registration_set+', to='contenttypes.contenttype')), ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_registration.registration_set+', to='contenttypes.ContentType')),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
], ],
options={ options={
@ -31,25 +35,16 @@ class Migration(migrations.Migration):
'verbose_name_plural': 'registrations', 'verbose_name_plural': 'registrations',
}, },
), ),
migrations.CreateModel(
name='AdminRegistration',
fields=[
('registration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.registration')),
('role', models.TextField(verbose_name='role of the administrator')),
],
options={
'verbose_name': 'admin registration',
'verbose_name_plural': 'admin registrations',
},
bases=('registration.registration',),
),
migrations.CreateModel( migrations.CreateModel(
name='ParticipantRegistration', name='ParticipantRegistration',
fields=[ fields=[
('registration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.registration')), ('registration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.Registration')),
('birth_date', models.DateField(default=datetime.date.today, verbose_name='birth date')),
('phone_number', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, region=None, verbose_name='phone number')),
('photo_authorization', models.FileField(blank=True, default='', upload_to=registration.models.get_random_photo_filename, verbose_name='photo authorization')), ('photo_authorization', models.FileField(blank=True, default='', upload_to=registration.models.get_random_photo_filename, verbose_name='photo authorization')),
('health_sheet', models.FileField(blank=True, default='', upload_to=registration.models.get_random_health_filename, verbose_name='health sheet')), ('health_sheet', models.FileField(blank=True, default='', upload_to=registration.models.get_random_health_filename, verbose_name='health sheet')),
('team', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='participants', to='participation.team', verbose_name='team')), ('address', address.models.AddressField(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='address.Address', verbose_name='address')),
('team', models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='participants', to='participation.Team', verbose_name='team')),
], ],
options={ options={
'abstract': False, 'abstract': False,
@ -60,7 +55,7 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='VolunteerRegistration', name='VolunteerRegistration',
fields=[ fields=[
('registration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.registration')), ('registration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.Registration')),
('professional_activity', models.TextField(verbose_name='professional activity')), ('professional_activity', models.TextField(verbose_name='professional activity')),
], ],
options={ options={
@ -69,10 +64,22 @@ class Migration(migrations.Migration):
}, },
bases=('registration.registration',), bases=('registration.registration',),
), ),
migrations.CreateModel(
name='AdminRegistration',
fields=[
('volunteerregistration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.VolunteerRegistration')),
('role', models.TextField(verbose_name='role of the administrator')),
],
options={
'verbose_name': 'admin registration',
'verbose_name_plural': 'admin registrations',
},
bases=('registration.volunteerregistration',),
),
migrations.CreateModel( migrations.CreateModel(
name='CoachRegistration', name='CoachRegistration',
fields=[ fields=[
('participantregistration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.participantregistration')), ('participantregistration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.ParticipantRegistration')),
('professional_activity', models.TextField(verbose_name='professional activity')), ('professional_activity', models.TextField(verbose_name='professional activity')),
], ],
options={ options={
@ -84,9 +91,12 @@ class Migration(migrations.Migration):
migrations.CreateModel( migrations.CreateModel(
name='StudentRegistration', name='StudentRegistration',
fields=[ fields=[
('participantregistration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.participantregistration')), ('participantregistration_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='registration.ParticipantRegistration')),
('student_class', models.IntegerField(choices=[(12, '12th grade'), (11, '11th grade'), (10, '10th grade or lower')], verbose_name='student class')), ('student_class', models.IntegerField(choices=[(12, '12th grade'), (11, '11th grade'), (10, '10th grade or lower')], verbose_name='student class')),
('school', models.CharField(max_length=255, verbose_name='school')), ('school', models.CharField(max_length=255, verbose_name='school')),
('responsible_name', models.CharField(default='', max_length=255, verbose_name='responsible name')),
('responsible_phone', phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, region=None, verbose_name='responsible phone number')),
('responsible_email', models.EmailField(default='', max_length=254, verbose_name='responsible email address')),
('parental_authorization', models.FileField(blank=True, default='', upload_to=registration.models.get_random_parental_filename, verbose_name='parental authorization')), ('parental_authorization', models.FileField(blank=True, default='', upload_to=registration.models.get_random_parental_filename, verbose_name='parental authorization')),
], ],
options={ options={

View File

@ -1,48 +0,0 @@
# Generated by Django 3.0.11 on 2020-12-28 21:19
import address.models
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import phonenumber_field.modelfields
class Migration(migrations.Migration):
dependencies = [
('address', '0003_auto_20200830_1851'),
('registration', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='participantregistration',
name='address',
field=address.models.AddressField(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='address.Address', verbose_name='address'),
),
migrations.AddField(
model_name='participantregistration',
name='birth_date',
field=models.DateField(default=django.utils.timezone.now, verbose_name='birth date'),
),
migrations.AddField(
model_name='participantregistration',
name='phone_number',
field=phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, region=None, verbose_name='phone number'),
),
migrations.AddField(
model_name='studentregistration',
name='responsible_email',
field=models.EmailField(default='', max_length=254, verbose_name='responsible email address'),
),
migrations.AddField(
model_name='studentregistration',
name='responsible_name',
field=models.CharField(default='', max_length=255, verbose_name='responsible name'),
),
migrations.AddField(
model_name='studentregistration',
name='responsible_phone',
field=phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, region=None, verbose_name='responsible phone number'),
),
]

View File

@ -259,7 +259,7 @@ class VolunteerRegistration(Registration):
return VolunteerRegistrationForm return VolunteerRegistrationForm
class AdminRegistration(Registration): class AdminRegistration(VolunteerRegistration):
""" """
Specific registration for admins. Specific registration for admins.
They have a field to justify they status. They have a field to justify they status.

View File

@ -233,3 +233,6 @@ PHONENUMBER_DB_FORMAT = 'NATIONAL'
PHONENUMBER_DEFAULT_REGION = 'FR' PHONENUMBER_DEFAULT_REGION = 'FR'
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
# Use local Jquery
JQUERY_URL = False

View File

@ -19,23 +19,15 @@
{% endif %} {% endif %}
{# Bootstrap CSS #} {# Bootstrap CSS #}
<link rel="stylesheet" <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh"
crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/v4-shims.css"> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/v4-shims.css">
{# JQuery, Bootstrap and Turbolinks JavaScript #} {# JQuery, Bootstrap and Turbolinks JavaScript #}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script>
integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh" <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
crossorigin="anonymous"></script> integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js" <script src="https://cdnjs.cloudflare.com/ajax/libs/turbolinks/5.2.0/turbolinks.js"
crossorigin="anonymous"></script> crossorigin="anonymous"></script>