mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 02:12:05 +01:00 
			
		
		
		
	Add some forms
This commit is contained in:
		@@ -1,4 +1,5 @@
 | 
				
			|||||||
from django.contrib.auth.forms import UserCreationForm
 | 
					from django.contrib.auth.forms import UserCreationForm
 | 
				
			||||||
 | 
					from django import forms
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from member.models import TFJMUser
 | 
					from member.models import TFJMUser
 | 
				
			||||||
@@ -37,3 +38,9 @@ class SignUpForm(UserCreationForm):
 | 
				
			|||||||
            'responsible_email',
 | 
					            'responsible_email',
 | 
				
			||||||
            'description',
 | 
					            'description',
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TFJMUserForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = TFJMUser
 | 
				
			||||||
 | 
					        fields = '__all__'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,15 @@
 | 
				
			|||||||
from django.urls import path
 | 
					from django.urls import path
 | 
				
			||||||
from django.views.generic import RedirectView
 | 
					from django.views.generic import RedirectView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .views import CreateUserView, ProfileListView, OrphanedProfileListView, OrganizersListView
 | 
					from .views import CreateUserView, MyAccountView, UserDetailView,\
 | 
				
			||||||
 | 
					    ProfileListView, OrphanedProfileListView, OrganizersListView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app_name = "member"
 | 
					app_name = "member"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    path('signup/', CreateUserView.as_view(), name="signup"),
 | 
					    path('signup/', CreateUserView.as_view(), name="signup"),
 | 
				
			||||||
    path("my-account/", RedirectView.as_view(pattern_name="index"), name="my_account"),
 | 
					    path("my-account/", MyAccountView.as_view(), name="my_account"),
 | 
				
			||||||
 | 
					    path("information/<int:pk>/", UserDetailView.as_view(), name="information"),
 | 
				
			||||||
    path("add-team/", RedirectView.as_view(pattern_name="index"), name="add_team"),
 | 
					    path("add-team/", RedirectView.as_view(pattern_name="index"), name="add_team"),
 | 
				
			||||||
    path("join-team/", RedirectView.as_view(pattern_name="index"), name="join_team"),
 | 
					    path("join-team/", RedirectView.as_view(pattern_name="index"), name="join_team"),
 | 
				
			||||||
    path("my-team/", RedirectView.as_view(pattern_name="index"), name="my_team"),
 | 
					    path("my-team/", RedirectView.as_view(pattern_name="index"), name="my_team"),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,11 +4,11 @@ from django.db.models import Q
 | 
				
			|||||||
from django.http import FileResponse
 | 
					from django.http import FileResponse
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
from django.views import View
 | 
					from django.views import View
 | 
				
			||||||
from django.views.generic import CreateView
 | 
					from django.views.generic import CreateView, UpdateView, DetailView
 | 
				
			||||||
from django_tables2 import SingleTableView
 | 
					from django_tables2 import SingleTableView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from tournament.views import AdminMixin
 | 
					from tournament.views import AdminMixin
 | 
				
			||||||
from .forms import SignUpForm
 | 
					from .forms import SignUpForm, TFJMUserForm
 | 
				
			||||||
from .models import TFJMUser, Document
 | 
					from .models import TFJMUser, Document
 | 
				
			||||||
from .tables import UserTable
 | 
					from .tables import UserTable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -19,6 +19,35 @@ class CreateUserView(CreateView):
 | 
				
			|||||||
    template_name = "registration/signup.html"
 | 
					    template_name = "registration/signup.html"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MyAccountView(LoginRequiredMixin, UpdateView):
 | 
				
			||||||
 | 
					    model = TFJMUser
 | 
				
			||||||
 | 
					    form_class = TFJMUserForm
 | 
				
			||||||
 | 
					    template_name = "member/my_account.html"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_object(self, queryset=None):
 | 
				
			||||||
 | 
					        return self.request.user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class UserDetailView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
 | 
					    model = TFJMUser
 | 
				
			||||||
 | 
					    form_class = TFJMUserForm
 | 
				
			||||||
 | 
					    context_object_name = "user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def dispatch(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        if not request.user.admin \
 | 
				
			||||||
 | 
					                and (self.object.team is not None and request.user not in self.object.team.tournament.organizers)\
 | 
				
			||||||
 | 
					                and self.request.user != self.object:
 | 
				
			||||||
 | 
					            raise PermissionDenied
 | 
				
			||||||
 | 
					        return super().dispatch(request, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_context_data(self, **kwargs):
 | 
				
			||||||
 | 
					        context = super().get_context_data(**kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context["title"] = str(self.object)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DocumentView(LoginRequiredMixin, View):
 | 
					class DocumentView(LoginRequiredMixin, View):
 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
        doc = Document.objects.get(file=self.kwargs["file"])
 | 
					        doc = Document.objects.get(file=self.kwargs["file"])
 | 
				
			||||||
@@ -29,7 +58,7 @@ class DocumentView(LoginRequiredMixin, View):
 | 
				
			|||||||
        return FileResponse(doc.file, content_type="application/pdf")
 | 
					        return FileResponse(doc.file, content_type="application/pdf")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProfileListView(LoginRequiredMixin, AdminMixin, SingleTableView):
 | 
					class ProfileListView(AdminMixin, SingleTableView):
 | 
				
			||||||
    model = TFJMUser
 | 
					    model = TFJMUser
 | 
				
			||||||
    queryset = TFJMUser.objects.order_by("role", "last_name", "first_name")
 | 
					    queryset = TFJMUser.objects.order_by("role", "last_name", "first_name")
 | 
				
			||||||
    table_class = UserTable
 | 
					    table_class = UserTable
 | 
				
			||||||
@@ -37,7 +66,7 @@ class ProfileListView(LoginRequiredMixin, AdminMixin, SingleTableView):
 | 
				
			|||||||
    extra_context = dict(title=_("All profiles"))
 | 
					    extra_context = dict(title=_("All profiles"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrphanedProfileListView(LoginRequiredMixin, AdminMixin, SingleTableView):
 | 
					class OrphanedProfileListView(AdminMixin, SingleTableView):
 | 
				
			||||||
    model = TFJMUser
 | 
					    model = TFJMUser
 | 
				
			||||||
    queryset = TFJMUser.objects.filter((Q(role="2coach") | Q(role="3participant")) & Q(team__isnull=True))\
 | 
					    queryset = TFJMUser.objects.filter((Q(role="2coach") | Q(role="3participant")) & Q(team__isnull=True))\
 | 
				
			||||||
        .order_by("role", "last_name", "first_name")
 | 
					        .order_by("role", "last_name", "first_name")
 | 
				
			||||||
@@ -46,7 +75,7 @@ class OrphanedProfileListView(LoginRequiredMixin, AdminMixin, SingleTableView):
 | 
				
			|||||||
    extra_context = dict(title=_("Orphaned profiles"))
 | 
					    extra_context = dict(title=_("Orphaned profiles"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OrganizersListView(LoginRequiredMixin, AdminMixin, SingleTableView):
 | 
					class OrganizersListView(AdminMixin, SingleTableView):
 | 
				
			||||||
    model = TFJMUser
 | 
					    model = TFJMUser
 | 
				
			||||||
    queryset = TFJMUser.objects.filter(Q(role="0admin") | Q(role="1volunteer"))\
 | 
					    queryset = TFJMUser.objects.filter(Q(role="0admin") | Q(role="1volunteer"))\
 | 
				
			||||||
        .order_by("role", "last_name", "first_name")
 | 
					        .order_by("role", "last_name", "first_name")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								apps/tournament/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								apps/tournament/forms.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					from django import forms
 | 
				
			||||||
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from member.models import TFJMUser
 | 
				
			||||||
 | 
					from tfjm.inputs import DatePickerInput, DateTimePickerInput, AmountInput
 | 
				
			||||||
 | 
					from tournament.models import Tournament, Team
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TournamentForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = Tournament
 | 
				
			||||||
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					        widgets = {
 | 
				
			||||||
 | 
					            "price": AmountInput(),
 | 
				
			||||||
 | 
					            "date_start": DatePickerInput(),
 | 
				
			||||||
 | 
					            "date_end": DatePickerInput(),
 | 
				
			||||||
 | 
					            "date_inscription": DateTimePickerInput(),
 | 
				
			||||||
 | 
					            "date_solutions": DateTimePickerInput(),
 | 
				
			||||||
 | 
					            "date_syntheses": DateTimePickerInput(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OrganizerForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = TFJMUser
 | 
				
			||||||
 | 
					        fields = ('last_name', 'first_name', 'email', 'is_superuser',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def save(self, commit=True):
 | 
				
			||||||
 | 
					        user = self.instance
 | 
				
			||||||
 | 
					        user.role = '0admin' if user.is_superuser else '1organizer'
 | 
				
			||||||
 | 
					        super().save(commit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TeamForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = Team
 | 
				
			||||||
 | 
					        fields = ('name', 'trigram', 'tournament',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class JoinTeam(forms.Form):
 | 
				
			||||||
 | 
					    access_code = forms.CharField(
 | 
				
			||||||
 | 
					        label=_("Access code"),
 | 
				
			||||||
 | 
					        max_length=6,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
@@ -2,6 +2,7 @@ import os
 | 
				
			|||||||
from datetime import date
 | 
					from datetime import date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
 | 
					from django.urls import reverse_lazy
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -145,10 +146,20 @@ class Team(models.Model):
 | 
				
			|||||||
    def encadrants(self):
 | 
					    def encadrants(self):
 | 
				
			||||||
        return self.users.all().filter(role="2coach")
 | 
					        return self.users.all().filter(role="2coach")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def linked_encadrants(self):
 | 
				
			||||||
 | 
					        return ['<a href="{url}">'.format(url=reverse_lazy("member:information", args=(user.pk,))) + str(user) + '</a>'
 | 
				
			||||||
 | 
					                for user in self.encadrants]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def participants(self):
 | 
					    def participants(self):
 | 
				
			||||||
        return self.users.all().filter(role="3participant")
 | 
					        return self.users.all().filter(role="3participant")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def linked_participants(self):
 | 
				
			||||||
 | 
					        return ['<a href="{url}">'.format(url=reverse_lazy("member:information", args=(user.pk,))) + str(user) + '</a>'
 | 
				
			||||||
 | 
					                for user in self.participants]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        verbose_name = _("team")
 | 
					        verbose_name = _("team")
 | 
				
			||||||
        verbose_name_plural = _("teams")
 | 
					        verbose_name_plural = _("teams")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,16 +1,19 @@
 | 
				
			|||||||
from django.urls import path
 | 
					from django.urls import path
 | 
				
			||||||
from django.views.generic import RedirectView
 | 
					from django.views.generic import RedirectView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .views import TournamentListView, TournamentDetailView, TeamDetailView, SolutionsView, SolutionsOrgaListView
 | 
					from .views import TournamentListView, TournamentCreateView, TournamentDetailView, TournamentUpdateView,\
 | 
				
			||||||
 | 
					    TeamDetailView, TeamUpdateView, AddOrganizerView, SolutionsView, SolutionsOrgaListView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app_name = "tournament"
 | 
					app_name = "tournament"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    path('list/', TournamentListView.as_view(), name="list"),
 | 
					    path('list/', TournamentListView.as_view(), name="list"),
 | 
				
			||||||
    path("add/", RedirectView.as_view(pattern_name="index"), name="add"),
 | 
					    path("add/", TournamentCreateView.as_view(), name="add"),
 | 
				
			||||||
    path('<int:pk>/', TournamentDetailView.as_view(), name="detail"),
 | 
					    path('<int:pk>/', TournamentDetailView.as_view(), name="detail"),
 | 
				
			||||||
 | 
					    path('<int:pk>/update/', TournamentUpdateView.as_view(), name="update"),
 | 
				
			||||||
    path('team/<int:pk>/', TeamDetailView.as_view(), name="team_detail"),
 | 
					    path('team/<int:pk>/', TeamDetailView.as_view(), name="team_detail"),
 | 
				
			||||||
    path("add-organizer/", RedirectView.as_view(pattern_name="index"), name="add_organizer"),
 | 
					    path('team/<int:pk>/update/', TeamUpdateView.as_view(), name="team_update"),
 | 
				
			||||||
 | 
					    path("add-organizer/", AddOrganizerView.as_view(), name="add_organizer"),
 | 
				
			||||||
    path("solutions/", SolutionsView.as_view(), name="solutions"),
 | 
					    path("solutions/", SolutionsView.as_view(), name="solutions"),
 | 
				
			||||||
    path("all-solutions/", SolutionsOrgaListView.as_view(), name="all_solutions"),
 | 
					    path("all-solutions/", SolutionsOrgaListView.as_view(), name="all_solutions"),
 | 
				
			||||||
    path("syntheses/", RedirectView.as_view(pattern_name="index"), name="syntheses"),
 | 
					    path("syntheses/", RedirectView.as_view(pattern_name="index"), name="syntheses"),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,23 +5,26 @@ from django.contrib.auth.mixins import LoginRequiredMixin
 | 
				
			|||||||
from django.core.exceptions import PermissionDenied
 | 
					from django.core.exceptions import PermissionDenied
 | 
				
			||||||
from django.db.models import Q
 | 
					from django.db.models import Q
 | 
				
			||||||
from django.http import HttpResponse
 | 
					from django.http import HttpResponse
 | 
				
			||||||
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
 | 
					from django.urls import reverse_lazy
 | 
				
			||||||
from django.utils.translation import gettext_lazy as _
 | 
					from django.utils.translation import gettext_lazy as _
 | 
				
			||||||
from django.views.generic import DetailView
 | 
					from django.views.generic import DetailView, CreateView, UpdateView
 | 
				
			||||||
from django_tables2.views import SingleTableView
 | 
					from django_tables2.views import SingleTableView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from member.models import TFJMUser, Solution
 | 
					from member.models import TFJMUser, Solution
 | 
				
			||||||
 | 
					from .forms import TournamentForm, OrganizerForm, TeamForm
 | 
				
			||||||
from .models import Tournament, Team
 | 
					from .models import Tournament, Team
 | 
				
			||||||
from .tables import TournamentTable, TeamTable, SolutionTable
 | 
					from .tables import TournamentTable, TeamTable, SolutionTable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AdminMixin(object):
 | 
					class AdminMixin(LoginRequiredMixin):
 | 
				
			||||||
    def dispatch(self, request, *args, **kwargs):
 | 
					    def dispatch(self, request, *args, **kwargs):
 | 
				
			||||||
        if not request.user.admin:
 | 
					        if not request.user.admin:
 | 
				
			||||||
            raise PermissionDenied
 | 
					            raise PermissionDenied
 | 
				
			||||||
        return super().dispatch(request, *args, **kwargs)
 | 
					        return super().dispatch(request, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TeamMixin(object):
 | 
					class TeamMixin(LoginRequiredMixin):
 | 
				
			||||||
    def dispatch(self, request, *args, **kwargs):
 | 
					    def dispatch(self, request, *args, **kwargs):
 | 
				
			||||||
        if not request.user.team:
 | 
					        if not request.user.team:
 | 
				
			||||||
            raise PermissionDenied
 | 
					            raise PermissionDenied
 | 
				
			||||||
@@ -47,6 +50,15 @@ class TournamentListView(SingleTableView):
 | 
				
			|||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TournamentCreateView(AdminMixin, CreateView):
 | 
				
			||||||
 | 
					    model = Tournament
 | 
				
			||||||
 | 
					    form_class = TournamentForm
 | 
				
			||||||
 | 
					    extra_context = dict(title=_("Add tournament"),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_success_url(self):
 | 
				
			||||||
 | 
					        return reverse_lazy('tournament:detail', args=(self.object.pk,))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TournamentDetailView(DetailView):
 | 
					class TournamentDetailView(DetailView):
 | 
				
			||||||
    model = Tournament
 | 
					    model = Tournament
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,6 +83,15 @@ class TournamentDetailView(DetailView):
 | 
				
			|||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TournamentUpdateView(AdminMixin, UpdateView):
 | 
				
			||||||
 | 
					    model = Tournament
 | 
				
			||||||
 | 
					    form_class = TournamentForm
 | 
				
			||||||
 | 
					    extra_context = dict(title=_("Update tournament"),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_success_url(self):
 | 
				
			||||||
 | 
					        return reverse_lazy('tournament:detail', args=(self.object.pk,))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TeamDetailView(LoginRequiredMixin, DetailView):
 | 
					class TeamDetailView(LoginRequiredMixin, DetailView):
 | 
				
			||||||
    model = Team
 | 
					    model = Team
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -97,6 +118,9 @@ class TeamDetailView(LoginRequiredMixin, DetailView):
 | 
				
			|||||||
                .format(_("Solutions for team {team}.zip")
 | 
					                .format(_("Solutions for team {team}.zip")
 | 
				
			||||||
                        .format(team=str(team)).replace(" ", "%20"))
 | 
					                        .format(team=str(team)).replace(" ", "%20"))
 | 
				
			||||||
            return resp
 | 
					            return resp
 | 
				
			||||||
 | 
					        elif "delete" in request.POST:
 | 
				
			||||||
 | 
					            team.delete()
 | 
				
			||||||
 | 
					            return redirect('tournament:detail', pk=team.tournament.pk)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return self.get(request, *args, **kwargs)
 | 
					        return self.get(request, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -108,7 +132,25 @@ class TeamDetailView(LoginRequiredMixin, DetailView):
 | 
				
			|||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SolutionsView(LoginRequiredMixin, TeamMixin, SingleTableView):
 | 
					class TeamUpdateView(LoginRequiredMixin, UpdateView):
 | 
				
			||||||
 | 
					    model = Team
 | 
				
			||||||
 | 
					    form_class = TeamForm
 | 
				
			||||||
 | 
					    extra_context = dict(title=_("Udpate team"),)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def dispatch(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        if not request.user.admin and self.request.user not in self.get_object().tournament.organizers:
 | 
				
			||||||
 | 
					            raise PermissionDenied
 | 
				
			||||||
 | 
					        return super().dispatch(request, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AddOrganizerView(AdminMixin, CreateView):
 | 
				
			||||||
 | 
					    model = TFJMUser
 | 
				
			||||||
 | 
					    form_class = OrganizerForm
 | 
				
			||||||
 | 
					    extra_context = dict(title=_("Add organizer"),)
 | 
				
			||||||
 | 
					    template_name = "tournament/add_organizer.html"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SolutionsView(TeamMixin, SingleTableView):
 | 
				
			||||||
    model = Solution
 | 
					    model = Solution
 | 
				
			||||||
    table_class = SolutionTable
 | 
					    table_class = SolutionTable
 | 
				
			||||||
    template_name = "tournament/solutions_list.html"
 | 
					    template_name = "tournament/solutions_list.html"
 | 
				
			||||||
@@ -149,7 +191,7 @@ class SolutionsView(LoginRequiredMixin, TeamMixin, SingleTableView):
 | 
				
			|||||||
        return qs.order_by('team__tournament__date_start', 'team__tournament__name', 'team__trigram', 'problem',)
 | 
					        return qs.order_by('team__tournament__date_start', 'team__tournament__name', 'team__trigram', 'problem',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SolutionsOrgaListView(LoginRequiredMixin, AdminMixin, SingleTableView):
 | 
					class SolutionsOrgaListView(AdminMixin, SingleTableView):
 | 
				
			||||||
    model = Solution
 | 
					    model = Solution
 | 
				
			||||||
    table_class = SolutionTable
 | 
					    table_class = SolutionTable
 | 
				
			||||||
    template_name = "tournament/solutions_orga_list.html"
 | 
					    template_name = "tournament/solutions_orga_list.html"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -442,7 +442,7 @@ msgstr "Liste des tournois"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#: apps/tournament/views.py:56
 | 
					#: apps/tournament/views.py:56
 | 
				
			||||||
msgid "Tournament of {name}"
 | 
					msgid "Tournament of {name}"
 | 
				
			||||||
msgstr "Tournoi de {user}"
 | 
					msgstr "Tournoi de {name}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: apps/tournament/views.py:97 apps/tournament/views.py:131
 | 
					#: apps/tournament/views.py:97 apps/tournament/views.py:131
 | 
				
			||||||
#, python-brace-format
 | 
					#, python-brace-format
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								templates/member/my_account.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								templates/member/my_account.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load i18n crispy_forms_filters %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <form method="post">
 | 
				
			||||||
 | 
					        {{ form|crispy }}
 | 
				
			||||||
 | 
					        <input type="submit" class="btn btn-primary btn-block" value="{% trans "Submit" %}">
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <hr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <a class="btn btn-secondary btn-block" href="{% url "password_change" %}">{% trans "Update my password" %}</a>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
							
								
								
									
										69
									
								
								templates/member/tfjmuser_detail.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								templates/member/tfjmuser_detail.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load getconfig i18n django_tables2 static %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <div class="card bg-light shadow">
 | 
				
			||||||
 | 
					        <div class="card-header text-center">
 | 
				
			||||||
 | 
					            <h4>{{ user }}</h4>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="card-body">
 | 
				
			||||||
 | 
					            <dl class="row">
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'role'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6">{{ user.get_role_display }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'team'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6"><a href="{% url "tournament:team_detail" pk=user.team.pk %}">{{ user.team }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'birth date'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6">{{ user.birth_date }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'gender'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6">{{ user.get_gender_display }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'address'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6">{{ user.address }}, {{ user.postal_code }}, {{ user.city }}{% if user.country != "France" %}, {{ user.country }}{% endif %}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'email'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6"><a href="mailto:{{ user.email }}">{{ user.email }}</a></dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <dt class="col-xl-6 text-right">{% trans 'phone number'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                <dd class="col-xl-6">{{ user.phone_number }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                {% if user.role == '3participant' %}
 | 
				
			||||||
 | 
					                    <dt class="col-xl-6 text-right">{% trans 'school'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                    <dd class="col-xl-6">{{ user.school }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <dt class="col-xl-6 text-right">{% trans 'class'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                    <dd class="col-xl-6">{{ user.get_student_class_display }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    {% if user.responsible_name %}
 | 
				
			||||||
 | 
					                        <dt class="col-xl-6 text-right">{% trans 'responsible name'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                        <dd class="col-xl-6">{{ user.responsible_name }}</dd>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    {% if user.responsible_phone %}
 | 
				
			||||||
 | 
					                        <dt class="col-xl-6 text-right">{% trans 'responsible phone'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                        <dd class="col-xl-6">{{ user.responsible_phone }}</dd>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    {% if user.responsible_email %}
 | 
				
			||||||
 | 
					                        <dt class="col-xl-6 text-right">{% trans 'responsible email'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                        <dd class="col-xl-6"><a href="{{ user.responsible_email }}">{{ user.responsible_email }}</a></dd>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
 | 
					                {% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                {% if user.role == '2coach' %}
 | 
				
			||||||
 | 
					                    <dt class="col-xl-6 text-right">{% trans 'description'|capfirst %}</dt>
 | 
				
			||||||
 | 
					                    <dd class="col-xl-6">{{ user.description }}</dd>
 | 
				
			||||||
 | 
					                {% endif %}
 | 
				
			||||||
 | 
					            </dl>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <hr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h4>{% trans "Documents" %}</h4>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    {# TODO Display documents #}
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
							
								
								
									
										11
									
								
								templates/tournament/add_organizer.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								templates/tournament/add_organizer.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load i18n crispy_forms_filters %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <form method="post">
 | 
				
			||||||
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					        {{ form|crispy }}
 | 
				
			||||||
 | 
					        <input type="submit" class="btn btn-primary btn-block" value="{% trans "Submit" %}">
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
@@ -19,18 +19,21 @@
 | 
				
			|||||||
                <dd class="col-xl-6">{{ team.tournament }}</dd>
 | 
					                <dd class="col-xl-6">{{ team.tournament }}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <dt class="col-xl-6 text-right">{% trans 'coachs'|capfirst %}</dt>
 | 
					                <dt class="col-xl-6 text-right">{% trans 'coachs'|capfirst %}</dt>
 | 
				
			||||||
                <dd class="col-xl-6">{{ team.encadrants.all|join:", " }}</dd>
 | 
					                <dd class="col-xl-6">{% autoescape off %}{{ team.linked_encadrants|join:", " }}{% endautoescape %}</dd>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <dt class="col-xl-6 text-right">{% trans 'participants'|capfirst %}</dt>
 | 
					                <dt class="col-xl-6 text-right">{% trans 'participants'|capfirst %}</dt>
 | 
				
			||||||
                <dd class="col-xl-6">{{ team.participants.all|join:", " }}</dd>
 | 
					                <dd class="col-xl-6">{% autoescape off %}{{ team.linked_participants|join:", " }}{% endautoescape %}</dd>
 | 
				
			||||||
            </dl>
 | 
					            </dl>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {% if user.admin or user in team.tournament.organizers.all %}
 | 
					        {% if user.admin or user in team.tournament.organizers.all %}
 | 
				
			||||||
            <div class="card-footer text-center">
 | 
					            <div class="card-footer text-center">
 | 
				
			||||||
                <button class="btn btn-secondary">{% trans "Edit team" %}</button>
 | 
					                <a href="{% url "tournament:team_update" pk=team.pk %}"><button class="btn btn-secondary">{% trans "Edit team" %}</button></a>
 | 
				
			||||||
                {% if user.admin and team.invalid %}
 | 
					                {% if user.admin and team.invalid %}
 | 
				
			||||||
                    <button class="btn btn-danger">{% trans "Delete team" %}</button>
 | 
					                    <form method="post">
 | 
				
			||||||
 | 
					                        {% csrf_token %}
 | 
				
			||||||
 | 
					                        <button name="delete" class="btn btn-danger">{% trans "Delete team" %}</button>
 | 
				
			||||||
 | 
					                    </form>
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								templates/tournament/team_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								templates/tournament/team_form.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load i18n crispy_forms_filters %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <form method="post">
 | 
				
			||||||
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					        {{ form|crispy }}
 | 
				
			||||||
 | 
					        <input type="submit" class="btn btn-primary btn-block" value="{% trans "Submit" %}">
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
@@ -39,15 +39,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            {% if user.is_authenticated and user.admin %}
 | 
					            {% if user.is_authenticated and user.admin %}
 | 
				
			||||||
                <div class="alert alert-info">
 | 
					                <div class="alert alert-info">
 | 
				
			||||||
                    <a href="mailto:contact@tfm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ team_users_emails|join:"," }}">{% trans "Send a mail to all people in this tournament" %}</a><br>
 | 
					                    <a href="mailto:contact@tfjm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ team_users_emails|join:"," }}">{% trans "Send a mail to all people in this tournament" %}</a><br>
 | 
				
			||||||
                    <a href="mailto:contact@tfm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ valid_team_users_emails|join:"," }}">{% trans "Send a mail to all people in this tournament that are in a valid team" %}</a>
 | 
					                    <a href="mailto:contact@tfjm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ valid_team_users_emails|join:"," }}">{% trans "Send a mail to all people in this tournament that are in a valid team" %}</a>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        {% if user.admin or user in tournament.organizers.all %}
 | 
					        {% if user.admin or user in tournament.organizers.all %}
 | 
				
			||||||
            <div class="card-footer text-center">
 | 
					            <div class="card-footer text-center">
 | 
				
			||||||
                <button class="btn btn-secondary">{% trans "Edit tournament" %}</button>
 | 
					                <a href="{% url "tournament:update" pk=tournament.pk %}"><button class="btn btn-secondary">{% trans "Edit tournament" %}</button></a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        {% endif %}
 | 
					        {% endif %}
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								templates/tournament/tournament_form.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								templates/tournament/tournament_form.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load i18n crispy_forms_filters %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <form method="post">
 | 
				
			||||||
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					        {{ form|crispy }}
 | 
				
			||||||
 | 
					        <input type="submit" class="btn btn-primary btn-block" value="{% trans "Submit" %}">
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
@@ -5,8 +5,8 @@
 | 
				
			|||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
    {% if user.is_authenticated and user.admin %}
 | 
					    {% if user.is_authenticated and user.admin %}
 | 
				
			||||||
        <div class="alert alert-info">
 | 
					        <div class="alert alert-info">
 | 
				
			||||||
            <a href="mailto:contact@tfm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ team_users_emails|join:"," }}">{% trans "Send a mail to all people that are in a team" %}</a><br>
 | 
					            <a href="mailto:contact@tfjm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ team_users_emails|join:"," }}">{% trans "Send a mail to all people that are in a team" %}</a><br>
 | 
				
			||||||
            <a href="mailto:contact@tfm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ valid_team_users_emails|join:"," }}">{% trans "Send a mail to all people that are in a valid team" %}</a>
 | 
					            <a href="mailto:contact@tfjm.org?subject=TFJM²%20{{ "TFJM_YEAR"|get_env }}&bcc={{ valid_team_users_emails|join:"," }}">{% trans "Send a mail to all people that are in a valid team" %}</a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
    {% render_table table %}
 | 
					    {% render_table table %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -89,6 +89,8 @@ TEMPLATES = [
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WSGI_APPLICATION = 'tfjm.wsgi.application'
 | 
					WSGI_APPLICATION = 'tfjm.wsgi.application'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -150,7 +152,7 @@ LANGUAGES = [
 | 
				
			|||||||
    ('fr', _('French')),
 | 
					    ('fr', _('French')),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TIME_ZONE = 'UTC'
 | 
					TIME_ZONE = 'Europe/Paris'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
USE_I18N = True
 | 
					USE_I18N = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user