Upload photo authorizations

This commit is contained in:
Yohann D'ANELLO 2020-09-24 22:40:10 +02:00
parent e1ca18085a
commit 468295f648
11 changed files with 148 additions and 36 deletions

View File

@ -1,6 +1,7 @@
from django import forms from django import forms
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .models import AdminRegistration, CoachRegistration, StudentRegistration from .models import AdminRegistration, CoachRegistration, StudentRegistration
@ -44,6 +45,18 @@ class StudentRegistrationForm(forms.ModelForm):
fields = ('student_class', 'school', 'give_contact_to_animath',) fields = ('student_class', 'school', 'give_contact_to_animath',)
class PhotoAuthorizationForm(forms.ModelForm):
def clean_photo_authorization(self):
file = self.files["photo_authorization"]
if file.content_type not in ["application/pdf", "image/png", "image/jpeg"]:
raise ValidationError(_("The uploaded file must be a PDF, PNG of JPEG file."))
return self.cleaned_data["photo_authorization"]
class Meta:
model = StudentRegistration
fields = ('photo_authorization',)
class CoachRegistrationForm(forms.ModelForm): class CoachRegistrationForm(forms.ModelForm):
class Meta: class Meta:
model = CoachRegistration model = CoachRegistration

View File

@ -0,0 +1,19 @@
# Generated by Django 3.1.1 on 2020-09-24 20:36
from django.db import migrations, models
import registration.models
class Migration(migrations.Migration):
dependencies = [
('registration', '0003_registration_email_confirmed'),
]
operations = [
migrations.AddField(
model_name='studentregistration',
name='photo_authorization',
field=models.FileField(blank=True, default='', upload_to=registration.models.get_random_filename, verbose_name='photo authorization'),
),
]

View File

@ -2,6 +2,7 @@ from corres2math.tokens import email_validation_token
from django.contrib.sites.models import Site from django.contrib.sites.models import Site
from django.db import models from django.db import models
from django.template import loader from django.template import loader
from django.utils.crypto import get_random_string
from django.utils.encoding import force_bytes from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode from django.utils.http import urlsafe_base64_encode
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -66,6 +67,10 @@ class Registration(PolymorphicModel):
verbose_name_plural = _("registrations") verbose_name_plural = _("registrations")
def get_random_filename(instance, filename):
return get_random_string(64)
class StudentRegistration(Registration): class StudentRegistration(Registration):
team = models.ForeignKey( team = models.ForeignKey(
"participation.Team", "participation.Team",
@ -90,6 +95,14 @@ class StudentRegistration(Registration):
verbose_name=_("school"), verbose_name=_("school"),
) )
# FIXME Fix permission access, mime type
photo_authorization = models.FileField(
verbose_name=_("photo authorization"),
upload_to=get_random_filename,
blank=True,
default="",
)
@property @property
def type(self): def type(self):
return _("student") return _("student")

View File

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

View File

@ -27,6 +27,13 @@
<dt class="col-sm-6 text-right">{% trans "School:" %}</dt> <dt class="col-sm-6 text-right">{% trans "School:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.school }}</dd> <dd class="col-sm-6">{{ user_object.registration.school }}</dd>
<dt class="col-sm-6 text-right">{% trans "Photo authorization:" %}</dt>
<dd class="col-sm-6">
{% if user_object.registration.photo_authorization %}
<a href="{{ user_object.registration.photo_authorization.url }}" data-turbolinks="false">{% trans "Download" %}</a>
{% endif %} <button class="btn btn-primary" data-toggle="modal" data-target="#uploadPhotoAuthorizationModal">{% trans "Replace" %}</button>
</dd>
{% elif user_object.registration.coachregistration %} {% elif user_object.registration.coachregistration %}
<dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt> <dt class="col-sm-6 text-right">{% trans "Profesional activity:" %}</dt>
<dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd> <dd class="col-sm-6">{{ user_object.registration.professional_activity }}</dd>
@ -44,11 +51,15 @@
</div> </div>
</div> </div>
{% trans "Update user" as modal_title %} {% trans "Update user" as modal_title %}
{% trans "Update" as modal_button %} {% trans "Update" as modal_button %}
{% url "registration:update_user" pk=user_object.pk as modal_action %} {% url "registration:update_user" pk=user_object.pk as modal_action %}
{% include "base_modal.html" with modal_id="updateUser" %} {% include "base_modal.html" with modal_id="updateUser" %}
{% trans "Upload photo authorization" as modal_title %}
{% trans "Upload" as modal_button %}
{% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk as modal_action %}
{% include "base_modal.html" with modal_id="uploadPhotoAuthorization" modal_enctype="multipart/form-data" %}
{% endblock %} {% endblock %}
{% block extrajavascript %} {% block extrajavascript %}
@ -59,6 +70,11 @@
if (!modalBody.html().trim()) if (!modalBody.html().trim())
modalBody.load("{% url "registration:update_user" pk=user_object.pk %} #form-content"); modalBody.load("{% url "registration:update_user" pk=user_object.pk %} #form-content");
}); });
$('button[data-target="#uploadPhotoAuthorizationModal"]').click(function() {
let modalBody = $("#uploadPhotoAuthorizationModal div.modal-body");
if (!modalBody.html().trim())
modalBody.load("{% url "registration:upload_user_photo_authorization" pk=user_object.registration.pk %} #form-content");
});
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,7 +1,7 @@
from django.urls import path from django.urls import path
from .views import MyAccountDetailView, SignupView, UserDetailView, UserResendValidationEmailView, UserUpdateView,\ from .views import MyAccountDetailView, SignupView, UserDetailView, UserResendValidationEmailView,\
UserValidateView, UserValidationEmailSentView UserUpdateView, UserUploadPhotoAuthorizationView, UserValidateView, UserValidationEmailSentView
app_name = "registration" app_name = "registration"
@ -14,4 +14,6 @@ urlpatterns = [
path("user/", MyAccountDetailView.as_view(), name="my_account_detail"), path("user/", MyAccountDetailView.as_view(), name="my_account_detail"),
path("user/<int:pk>/", UserDetailView.as_view(), name="user_detail"), path("user/<int:pk>/", UserDetailView.as_view(), name="user_detail"),
path("user/<int:pk>/update/", UserUpdateView.as_view(), name="update_user"), path("user/<int:pk>/update/", UserUpdateView.as_view(), name="update_user"),
path("user/<int:pk>/upload-photo-authorization/", UserUploadPhotoAuthorizationView.as_view(),
name="upload_user_photo_authorization"),
] ]

View File

@ -10,7 +10,8 @@ from django.utils.http import urlsafe_base64_decode
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView from django.views.generic import CreateView, DetailView, RedirectView, TemplateView, UpdateView
from .forms import CoachRegistrationForm, SignupForm, StudentRegistrationForm, UserForm from .forms import CoachRegistrationForm, PhotoAuthorizationForm, SignupForm, StudentRegistrationForm, UserForm
from .models import StudentRegistration
class SignupView(CreateView): class SignupView(CreateView):
@ -156,3 +157,12 @@ class UserUpdateView(LoginRequiredMixin, UpdateView):
def get_success_url(self): def get_success_url(self):
return reverse_lazy("registration:user_detail", args=(self.object.pk,)) return reverse_lazy("registration:user_detail", args=(self.object.pk,))
class UserUploadPhotoAuthorizationView(LoginRequiredMixin, UpdateView):
model = StudentRegistration
form_class = PhotoAuthorizationForm
template_name = "registration/upload_photo_authorization.html"
def get_success_url(self):
return reverse_lazy("registration:user_detail", args=(self.object.user.pk,))

View File

@ -13,12 +13,14 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path 1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from django.views.defaults import bad_request, permission_denied, page_not_found, server_error from django.views.defaults import bad_request, permission_denied, page_not_found, server_error
from django.views.generic import TemplateView from django.views.generic import TemplateView
from corres2math import settings
urlpatterns = [ urlpatterns = [
path('', TemplateView.as_view(template_name="index.html"), name='index'), path('', TemplateView.as_view(template_name="index.html"), name='index'),
path('i18n/', include('django.conf.urls.i18n')), path('i18n/', include('django.conf.urls.i18n')),
@ -33,6 +35,9 @@ urlpatterns = [
path('', include('eastereggs.urls')), path('', include('eastereggs.urls')),
] ]
# FIXME Protect files
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
handler400 = bad_request handler400 = bad_request
handler403 = permission_denied handler403 = permission_denied
handler404 = page_not_found handler404 = page_not_found

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Corres2math\n" "Project-Id-Version: Corres2math\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-24 21:42+0200\n" "POT-Creation-Date: 2020-09-24 22:01+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n" "Last-Translator: Yohann D'ANELLO <yohann.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -38,7 +38,7 @@ msgstr "Fermer"
msgid "Logs" msgid "Logs"
msgstr "Logs" msgstr "Logs"
#: apps/logs/models.py:22 apps/registration/models.py:17 #: apps/logs/models.py:22 apps/registration/models.py:15
msgid "user" msgid "user"
msgstr "utilisateur" msgstr "utilisateur"
@ -141,7 +141,7 @@ msgid "Team {name} ({trigram})"
msgstr "Équipe {name} ({trigram})" msgstr "Équipe {name} ({trigram})"
#: apps/participation/models.py:45 apps/participation/models.py:56 #: apps/participation/models.py:45 apps/participation/models.py:56
#: apps/registration/models.py:78 apps/registration/models.py:123 #: apps/registration/models.py:76 apps/registration/models.py:121
msgid "team" msgid "team"
msgstr "équipe" msgstr "équipe"
@ -259,8 +259,8 @@ msgstr "Autoriser Animath à publier notre vidéo :"
#: apps/participation/templates/participation/team_detail.html:42 #: apps/participation/templates/participation/team_detail.html:42
#: apps/participation/templates/participation/update_team.html:12 #: apps/participation/templates/participation/update_team.html:12
#: apps/registration/templates/registration/update_user.html:12 #: apps/registration/templates/registration/update_user.html:12
#: apps/registration/templates/registration/user_detail.html:43 #: apps/registration/templates/registration/user_detail.html:50
#: apps/registration/templates/registration/user_detail.html:49 #: apps/registration/templates/registration/user_detail.html:55
msgid "Update" msgid "Update"
msgstr "Modifier" msgstr "Modifier"
@ -302,92 +302,92 @@ msgstr "rôle"
msgid "participant" msgid "participant"
msgstr "participant" msgstr "participant"
#: apps/registration/forms.py:14 apps/registration/models.py:132 #: apps/registration/forms.py:14 apps/registration/models.py:130
msgid "coach" msgid "coach"
msgstr "encadrant" msgstr "encadrant"
#: apps/registration/models.py:22 #: apps/registration/models.py:20
msgid "Grant Animath to contact me in the future about other actions" msgid "Grant Animath to contact me in the future about other actions"
msgstr "" msgstr ""
"Autoriser Animath à me recontacter à l'avenir à propos d'autres actions" "Autoriser Animath à me recontacter à l'avenir à propos d'autres actions"
#: apps/registration/models.py:27 #: apps/registration/models.py:25
msgid "email confirmed" msgid "email confirmed"
msgstr "email confirmé" msgstr "email confirmé"
#: apps/registration/models.py:31 #: apps/registration/models.py:29
msgid "Activate your Correspondances account" msgid "Activate your Correspondances account"
msgstr "Activez votre compte des Correspondances" msgstr "Activez votre compte des Correspondances"
#: apps/registration/models.py:67 #: apps/registration/models.py:65
msgid "registration" msgid "registration"
msgstr "inscription" msgstr "inscription"
#: apps/registration/models.py:68 #: apps/registration/models.py:66
msgid "registrations" msgid "registrations"
msgstr "inscriptions" msgstr "inscriptions"
#: apps/registration/models.py:83 #: apps/registration/models.py:81
msgid "12th grade" msgid "12th grade"
msgstr "Terminale" msgstr "Terminale"
#: apps/registration/models.py:84 #: apps/registration/models.py:82
msgid "11th grade" msgid "11th grade"
msgstr "Première" msgstr "Première"
#: apps/registration/models.py:85 #: apps/registration/models.py:83
msgid "10th grade or lower" msgid "10th grade or lower"
msgstr "Seconde ou inférieur" msgstr "Seconde ou inférieur"
#: apps/registration/models.py:87 #: apps/registration/models.py:85
msgid "student class" msgid "student class"
msgstr "classe" msgstr "classe"
#: apps/registration/models.py:92 #: apps/registration/models.py:90
msgid "school" msgid "school"
msgstr "école" msgstr "école"
#: apps/registration/models.py:96 #: apps/registration/models.py:94
msgid "photo authorization" msgid "photo authorization"
msgstr "" msgstr "autorisation de droit à l'image"
#: apps/registration/models.py:104 #: apps/registration/models.py:102
msgid "student" msgid "student"
msgstr "étudiant" msgstr "étudiant"
#: apps/registration/models.py:112 #: apps/registration/models.py:110
msgid "student registration" msgid "student registration"
msgstr "inscription d'élève" msgstr "inscription d'élève"
#: apps/registration/models.py:113 #: apps/registration/models.py:111
msgid "student registrations" msgid "student registrations"
msgstr "inscriptions d'élève" msgstr "inscriptions d'élève"
#: apps/registration/models.py:127 #: apps/registration/models.py:125
msgid "professional activity" msgid "professional activity"
msgstr "activité professionnelle" msgstr "activité professionnelle"
#: apps/registration/models.py:140 #: apps/registration/models.py:138
msgid "coach registration" msgid "coach registration"
msgstr "inscription d'encadrant" msgstr "inscription d'encadrant"
#: apps/registration/models.py:141 #: apps/registration/models.py:139
msgid "coach registrations" msgid "coach registrations"
msgstr "inscriptions d'encadrants" msgstr "inscriptions d'encadrants"
#: apps/registration/models.py:146 #: apps/registration/models.py:144
msgid "role of the administrator" msgid "role of the administrator"
msgstr "rôle de l'administrateur" msgstr "rôle de l'administrateur"
#: apps/registration/models.py:151 #: apps/registration/models.py:149
msgid "admin" msgid "admin"
msgstr "admin" msgstr "admin"
#: apps/registration/models.py:159 #: apps/registration/models.py:157
msgid "admin registration" msgid "admin registration"
msgstr "inscription d'administrateur" msgstr "inscription d'administrateur"
#: apps/registration/models.py:160 #: apps/registration/models.py:158
msgid "admin registrations" msgid "admin registrations"
msgstr "inscriptions d'administrateur" msgstr "inscriptions d'administrateur"
@ -542,6 +542,11 @@ msgstr "Réinitialiser mon mot de passe"
msgid "Sign up" msgid "Sign up"
msgstr "Inscription" msgstr "Inscription"
#: apps/registration/templates/registration/upload_photo_authorization.html:11
#: apps/registration/templates/registration/user_detail.html:60
msgid "Upload"
msgstr "Téléverser"
#: apps/registration/templates/registration/user_detail.html:14 #: apps/registration/templates/registration/user_detail.html:14
msgid "Last name:" msgid "Last name:"
msgstr "Nom de famille :" msgstr "Nom de famille :"
@ -571,21 +576,37 @@ msgid "School:"
msgstr "École :" msgstr "École :"
#: apps/registration/templates/registration/user_detail.html:31 #: apps/registration/templates/registration/user_detail.html:31
msgid "Photo authorization:"
msgstr "Autorisation de droit à l'image"
#: apps/registration/templates/registration/user_detail.html:34
msgid "Download"
msgstr "Télécharger"
#: apps/registration/templates/registration/user_detail.html:35
msgid "Replace"
msgstr "Remplacer"
#: apps/registration/templates/registration/user_detail.html:38
msgid "Profesional activity:" msgid "Profesional activity:"
msgstr "Activité professionnelle :" msgstr "Activité professionnelle :"
#: apps/registration/templates/registration/user_detail.html:34 #: apps/registration/templates/registration/user_detail.html:41
msgid "Role:" msgid "Role:"
msgstr "Rôle :" msgstr "Rôle :"
#: apps/registration/templates/registration/user_detail.html:38 #: apps/registration/templates/registration/user_detail.html:45
msgid "Grant Animath to contact me in the future about other actions:" msgid "Grant Animath to contact me in the future about other actions:"
msgstr "Autorise Animath à recontacter à propos d'autres actions :" msgstr "Autorise Animath à recontacter à propos d'autres actions :"
#: apps/registration/templates/registration/user_detail.html:48 #: apps/registration/templates/registration/user_detail.html:54
msgid "Update user" msgid "Update user"
msgstr "Modifier l'utilisateur" msgstr "Modifier l'utilisateur"
#: apps/registration/templates/registration/user_detail.html:59
msgid "Upload photo authorization"
msgstr "Téléverser l'autorisation de droit à l'image"
#: apps/registration/views.py:56 #: apps/registration/views.py:56
msgid "Email validation" msgid "Email validation"
msgstr "Validation de l'adresse mail" msgstr "Validation de l'adresse mail"