From cce3a0a7dffc2f88a9509c8d0eb6546b81d9f570 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Wed, 23 Sep 2020 23:20:44 +0200 Subject: [PATCH] Create and join teams forms --- apps/participation/forms.py | 14 ++++++- apps/participation/migrations/0001_initial.py | 2 +- apps/participation/models.py | 8 +++- apps/participation/views.py | 40 +++++++++++++++++++ apps/registration/models.py | 4 -- corres2math/middlewares.py | 4 +- locale/fr/LC_MESSAGES/django.po | 10 +++-- 7 files changed, 69 insertions(+), 13 deletions(-) diff --git a/apps/participation/forms.py b/apps/participation/forms.py index 33a6f24..7217f7c 100644 --- a/apps/participation/forms.py +++ b/apps/participation/forms.py @@ -1,10 +1,19 @@ +import re + from django import forms from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ from .models import Team class TeamForm(forms.ModelForm): + def clean_trigram(self): + trigram = self.cleaned_data["trigram"].upper() + if not re.match("[A-Z]{3}", trigram): + raise ValidationError(_("The trigram must be composed of three uppercase letters.")) + return trigram + class Meta: model = Team fields = ('name', 'trigram', 'grant_animath_access_videos',) @@ -14,13 +23,14 @@ class JoinTeamForm(forms.ModelForm): def clean_access_code(self): access_code = self.cleaned_data["access_code"] if not Team.objects.filter(access_code=access_code).exists(): - raise ValidationError("No team was found with this access code.") + raise ValidationError(_("No team was found with this access code.")) return access_code def clean(self): cleaned_data = super().clean() if "access_code" in cleaned_data: - self.instance = Team.objects.get(access_code=cleaned_data["access_code"]) + team = Team.objects.get(access_code=cleaned_data["access_code"]) + self.instance = team return cleaned_data class Meta: diff --git a/apps/participation/migrations/0001_initial.py b/apps/participation/migrations/0001_initial.py index 064884d..3618606 100644 --- a/apps/participation/migrations/0001_initial.py +++ b/apps/participation/migrations/0001_initial.py @@ -29,7 +29,7 @@ class Migration(migrations.Migration): fields=[ ('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')), - ('trigram', models.CharField(help_text='The trigram must be composed of 3 uppercase letters.', max_length=3, unique=True, validators=[django.core.validators.RegexValidator('[A-Z]{3}')], verbose_name='trigram')), + ('trigram', models.CharField(help_text='The trigram must be composed of three uppercase letters.', max_length=3, unique=True, validators=[django.core.validators.RegexValidator('[A-Z]{3}')], verbose_name='trigram')), ('access_code', models.CharField(help_text='The access code let other people to join the team.', max_length=6, verbose_name='access code')), ], options={ diff --git a/apps/participation/models.py b/apps/participation/models.py index 6584c9b..70c07f6 100644 --- a/apps/participation/models.py +++ b/apps/participation/models.py @@ -1,6 +1,7 @@ from django.core.validators import RegexValidator from django.db import models from django.db.models import Index +from django.utils.crypto import get_random_string from django.utils.translation import gettext_lazy as _ @@ -14,7 +15,7 @@ class Team(models.Model): trigram = models.CharField( max_length=3, verbose_name=_("trigram"), - help_text=_("The trigram must be composed of 3 uppercase letters."), + help_text=_("The trigram must be composed of three uppercase letters."), unique=True, validators=[RegexValidator("[A-Z]{3}")], ) @@ -31,6 +32,11 @@ class Team(models.Model): default=False, ) + def save(self, *args, **kwargs): + if not self.access_code: + self.access_code = get_random_string(6) + return super().save(*args, **kwargs) + def __str__(self): return _("Team {name} ({trigram})").format(name=self.name, trigram=self.trigram) diff --git a/apps/participation/views.py b/apps/participation/views.py index d62b2e6..c64e239 100644 --- a/apps/participation/views.py +++ b/apps/participation/views.py @@ -1,4 +1,6 @@ from django.contrib.auth.mixins import LoginRequiredMixin +from django.db import transaction +from django.urls import reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, FormView @@ -12,9 +14,47 @@ class CreateTeamView(LoginRequiredMixin, CreateView): extra_context = dict(title=_("Create team")) template_name = "participation/create_team.html" + @transaction.atomic + def form_valid(self, form): + user = self.request.user + registration = user.registration + if not registration.participates: + form.add_error(None, _("You don't participate, so you can't create a team.")) + return self.form_invalid(form) + elif registration.team: + form.add_error(None, _("You are already in a team.")) + return self.form_invalid(form) + + ret = super().form_valid(form) + registration.team = form.instance + registration.save() + return ret + + def get_success_url(self): + return reverse_lazy("index") + class JoinTeamView(LoginRequiredMixin, FormView): model = Team form_class = JoinTeamForm extra_context = dict(title=_("Join team")) template_name = "participation/create_team.html" + + @transaction.atomic + def form_valid(self, form): + user = self.request.user + registration = user.registration + if not registration.participates: + form.add_error(None, _("You don't participate, so you can't create a team.")) + return self.form_invalid(form) + elif registration.team: + form.add_error(None, _("You are already in a team.")) + return self.form_invalid(form) + + ret = super().form_valid(form) + registration.team = form.instance + registration.save() + return ret + + def get_success_url(self): + return reverse_lazy("index") diff --git a/apps/registration/models.py b/apps/registration/models.py index 2a6ef2c..ba07633 100644 --- a/apps/registration/models.py +++ b/apps/registration/models.py @@ -26,10 +26,6 @@ class Registration(PolymorphicModel): verbose_name=_("email confirmed"), ) - def save(self, *args, **kwargs): - self.send_email_validation_link() - return super().save(*args, **kwargs) - def send_email_validation_link(self): subject = "[Corres2math] " + str(_("Activate your Correspondances account")) token = email_validation_token.make_token(self.user) diff --git a/corres2math/middlewares.py b/corres2math/middlewares.py index fa1b83b..185eda9 100644 --- a/corres2math/middlewares.py +++ b/corres2math/middlewares.py @@ -50,8 +50,8 @@ class SessionMiddleware(object): request.user = User.objects.get(pk=request.session["_fake_user_id"]) user = request.user - if 'HTTP_X_FORWARDED_FOR' in request.META: - ip = request.META.get('HTTP_X_FORWARDED_FOR') + if 'HTTP_X_REAL_IP' in request.META: + ip = request.META.get('HTTP_X_REAL_IP') else: ip = request.META.get('REMOTE_ADDR') diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index 648fa97..9af56fd 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Corres2math\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-09-22 21:19+0200\n" +"POT-Creation-Date: 2020-09-22 21:26+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Yohann D'ANELLO \n" "Language-Team: LANGUAGE \n" @@ -101,6 +101,10 @@ msgstr "changelogs" msgid "Changelog of type \"{action}\" for model {model} at {timestamp}" msgstr "Changelog de type \"{action}\" pour le modèle {model} le {timestamp}" +#: apps/participation/forms.py:26 +msgid "No team was found with this access code." +msgstr "Aucune équipe n'a été trouvée avec ce code d'accès." + #: apps/participation/models.py:10 msgid "name" msgstr "nom" @@ -110,8 +114,8 @@ msgid "trigram" msgstr "trigramme" #: apps/participation/models.py:17 -msgid "The trigram must be composed of 3 uppercase letters." -msgstr "Le trigramme doit être composé de 3 lettres majuscules." +msgid "The trigram must be composed of three uppercase letters." +msgstr "Le trigramme doit être composé de trois lettres majuscules." #: apps/participation/models.py:24 msgid "access code"