From 4e1cf95bfb62af1a8444a7ee2510e1cf91d2421d Mon Sep 17 00:00:00 2001 From: Davy39 Date: Sat, 22 Jan 2022 12:34:38 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Mise=20=C3=A0=20jour=20des=20formulaires?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + djangoLxp/settings.py | 1 + djangoLxp/urls.py | 5 +- inscription/filters.py | 6 +- inscription/forms.py | 114 +++++++++---------- inscription/management/commands/pays.py | 22 ++++ inscription/management/commands/sociopro.py | 22 ++++ inscription/models.py | 99 ++++++++++------ inscription/utils.py | 4 +- inscription/views.py | 16 ++- migrations/inscription/0001_initial.py | 60 +++++++--- requirements.txt | 4 +- templates/inscription/fiche_inscription.html | 2 +- 13 files changed, 228 insertions(+), 128 deletions(-) create mode 100644 inscription/management/commands/pays.py create mode 100644 inscription/management/commands/sociopro.py diff --git a/.gitignore b/.gitignore index c78580c..807cc34 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .idea/ mediafiles/ +staticfiles/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/djangoLxp/settings.py b/djangoLxp/settings.py index 7e92d3f..6793b0f 100644 --- a/djangoLxp/settings.py +++ b/djangoLxp/settings.py @@ -58,6 +58,7 @@ 'leaflet', 'dal_select2', 'dal', + "phonenumber_field", ] MIDDLEWARE = [ diff --git a/djangoLxp/urls.py b/djangoLxp/urls.py index 96e8b26..10d8f5a 100644 --- a/djangoLxp/urls.py +++ b/djangoLxp/urls.py @@ -2,11 +2,12 @@ from django.contrib import admin from django.urls import re_path as url from inscription.models import Commune -from inscription.views import Autocomplete +from inscription.views import AutocompleteCommune, AutocompletePays urlpatterns = [ path('admin/', admin.site.urls), path('', include('inscription.urls')), path('captcha/', include('captcha.urls')), - url('^linked_data/$', Autocomplete.as_view(model=Commune), name='linked_data'), + url('^linked_data/$', AutocompleteCommune.as_view(model=Commune), name='linked_data'), + url('^pays/$', AutocompletePays.as_view(), name='pays'), ] \ No newline at end of file diff --git a/inscription/filters.py b/inscription/filters.py index ceafa49..86e9042 100644 --- a/inscription/filters.py +++ b/inscription/filters.py @@ -6,7 +6,7 @@ class ListeEleveFiltre(django_filters.FilterSet): class Meta: model = BaseEleve fields = { - "last_name": ["icontains"], - "first_name": ["exact"], + "nom": ["icontains"], + "prenom": ["exact"], } - order_by = ["last_name"] + order_by = ["nom"] diff --git a/inscription/forms.py b/inscription/forms.py index 334b429..5a8e3c8 100644 --- a/inscription/forms.py +++ b/inscription/forms.py @@ -28,8 +28,8 @@ class ListeEleveForm(FormHelper): Div( # les champs à chercher suivi de __filtre avec le nom du filtre déclaré pour chaque champ dans filter.py # InlineField("birth_name__icontains", css_class='form-group col-4'), - InlineField("first_name", wrapper_class='col'), - InlineField("last_name__icontains", wrapper_class='col'), + InlineField("prenom_name", wrapper_class='col'), + InlineField("nom__icontains", wrapper_class='col'), css_class="row", ), css_class="col-10 border p-3", @@ -49,7 +49,8 @@ class InscriptionForm1(forms.ModelForm): """ ### Le nom du formulaire, affiché dans le template (wizard.form.name) name = 'Identité' - + # mail de confirmation + confirmation_email = forms.EmailField(label="Confirmation de l'email", required=False) def __init__(self, *args, **kwargs): """ Surcharge de l'initialisation du formulaire @@ -66,43 +67,66 @@ def __init__(self, *args, **kwargs): # Liste des champs du modèle à afficher self.helper.layout = Layout( 'civility', - 'last_name', - 'first_name', + 'genre', + 'nom', + 'prenom', + 'pays_naissance', 'departement_naissance', 'commune_naissance', - 'birth_date', - 'birth_place', - 'birth_country', + 'date_naissance', 'address', + 'telephone', 'photo', + 'email', + 'confirmation_email', ) def clean(self): """Fonction pour contrôler les entrées""" - last_name = self.cleaned_data['last_name'] - first_name = self.cleaned_data['first_name'] + nom = self.cleaned_data['nom'] + prenom = self.cleaned_data['prenom'] # On vérifie que le couple Nom/Prénom n'est pas déjà dans la base - check = BaseEleve.objects.filter(first_name=first_name).filter(last_name=last_name) + check = BaseEleve.objects.filter(nom=nom).filter(prenom=prenom) # On exlut l'entrée en cours de cette recherche pour permettre les updates if self.instance: check = check.exclude(id=self.instance.id) # On affiche le message d'erreur if check.exists(): - msg = "{} {} est déjà dans la base.".format(first_name, last_name) - self.add_error('last_name', msg) - self.add_error('first_name', msg) + msg = "{} {} est déjà dans la base.".format(nom, prenom) + self.add_error('nom', msg) + self.add_error('prenom', msg) + + def clean_confirmation_mail(self): + """ + Méthode pour vérifier que le mail correspond bien au + mail de confirmation lors de la validation du formulaire + """ + confirmation_email = self.cleaned_data['confirmation_email'] + mail = self.cleaned_data['email'] + # Si l'instance (model) a déjà une ID c'est à dire que c'est un Update d'une entrée existante + if self.instance.id: + # On vérifie juste que l'email n'a pas été changé + if mail == self.instance.email: + return confirmation_email + # Si c'est une nouvelle entrée ou si l'email à changé, on compare l'email et la confirmation + if mail != confirmation_email: + raise forms.ValidationError( + "Le mail et le mail de confirmation ne sont pas identiques") + return confirmation_email + class Meta: # Modèle utilisé et entrées à renseigner model = BaseEleve - fields = ['address', 'civility', 'last_name', 'first_name', 'birth_date', 'birth_place', 'birth_country', - 'photo', 'commune_naissance', 'departement_naissance'] + fields = ['address', 'civility', 'genre', 'nom', 'prenom', 'date_naissance', 'pays_naissance', + 'photo', 'commune_naissance', 'departement_naissance', 'telephone', 'email', 'confirmation_email'] # Ajout d'un date picker au format='%Y-%m-%d' pour qu'il affiche les valeurs initiales lors des update # https://stackoverflow.com/questions/58294769/django-forms-dateinput-not-populating-from-instance widgets = { - 'birth_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}), + 'date_naissance': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}), 'commune_naissance': autocomplete.ModelSelect2(url='linked_data', - forward=('departement_naissance',)) + forward=('departement_naissance',)), + 'pays_naissance': autocomplete.ModelSelect2(url='pays') } class Media: @@ -111,7 +135,7 @@ class Media: ) class InscriptionForm2(forms.ModelForm): - name = 'Adresse' + name = 'Responsables légaux' def __init__(self, *args, **kwargs): """ @@ -129,38 +153,26 @@ def __init__(self, *args, **kwargs): # Affichage de ton formulaire self.helper.layout = Layout( # Liste des champs à afficher - 'street_number', - 'street_type', - 'street', - 'comp_1', - 'comp_2', - 'city', - 'zip_code', - 'country', - 'phone', + 'type_resp1', 'nom_resp1', 'prenom_resp1', 'adresse_resp1', 'tel_resp1', 'email_resp1', 'sociopro_resp1', + 'resp2', 'type_resp2','nom_resp2', 'prenom_resp2', 'adresse_resp2', 'tel_resp2', 'email_resp2', + 'sociopro_resp2', + ) class Meta: # Modèle utilisé et entrées à renseigner model = BaseEleve - fields = ['street_number', - 'street_type', - 'street', - 'comp_1', - 'comp_2', - 'city', - 'zip_code', - 'country', - 'phone', ] + fields = ['nom_resp1','prenom_resp1', 'nom_resp2', 'prenom_resp2', 'adresse_resp1', 'adresse_resp2', + 'tel_resp1', 'tel_resp2', 'email_resp1', 'email_resp2', 'sociopro_resp1', 'sociopro_resp2', + 'type_resp1', 'type_resp2', 'resp2'] class InscriptionForm3(forms.ModelForm): - name = 'Validation' + name = 'Scolarité' # Ajout des champs supplémentaires au modèle # captcha captcha = CaptchaWizardField() - # mail de confirmation - confirmation_mail = forms.EmailField(label="Mail de confirmation", required=False) + def __init__(self, *args, **kwargs): """ @@ -179,34 +191,14 @@ def __init__(self, *args, **kwargs): # Affichage du formulaire self.helper.layout = Layout( # Liste des champs à afficher dont les champs supplémentaires - 'mail', - 'confirmation_mail', 'comments', 'captcha', ) - def clean_confirmation_mail(self): - """ - Méthode pour vérifier que le mail correspond bien au - mail de confirmation lors de la validation du formulaire - """ - confirmation_mail = self.cleaned_data['confirmation_mail'] - mail = self.cleaned_data['mail'] - # Si l'instance (model) a déjà une ID c'est à dire que c'est un Update d'une entrée existante - if self.instance.id: - # On vérifie juste que l'email n'a pas été changé - if mail == self.instance.mail: - return confirmation_mail - # Si c'est une nouvelle entrée ou si l'email à changé, on compare l'email et la confirmation - if mail != confirmation_mail: - raise forms.ValidationError( - "Le mail et le mail de confirmation ne sont pas identiques") - return confirmation_mail - class Meta: # Définis le modèle utilisé et des données à enregistrer model = BaseEleve fields = [ - 'mail', + 'email', 'comments', ] diff --git a/inscription/management/commands/pays.py b/inscription/management/commands/pays.py new file mode 100644 index 0000000..c95a5cc --- /dev/null +++ b/inscription/management/commands/pays.py @@ -0,0 +1,22 @@ +import csv +from django.core.management import BaseCommand +from django.utils import timezone + +from inscription.models import Pays + + +class Command(BaseCommand): + help = "Charge la liste des pays depuis un fichier CSV." + + def handle(self, *args, **options): + start_time = timezone.now() + with open('inscription/data/pays.csv', "r") as csv_file: + data = list(csv.reader(csv_file, delimiter=";")) + for row in data: + Pays.objects.create(code=row[0], name=row[1]) + end_time = timezone.now() + self.stdout.write( + self.style.SUCCESS( + f"Le chargement a pris: {(end_time-start_time).total_seconds()} seconds." + ) + ) diff --git a/inscription/management/commands/sociopro.py b/inscription/management/commands/sociopro.py new file mode 100644 index 0000000..81736c0 --- /dev/null +++ b/inscription/management/commands/sociopro.py @@ -0,0 +1,22 @@ +import csv +from django.core.management import BaseCommand +from django.utils import timezone + +from inscription.models import Sociopro + + +class Command(BaseCommand): + help = "Charge la liste des catégories sociopro depuis un fichier CSV." + + def handle(self, *args, **options): + start_time = timezone.now() + with open('inscription/data/sociopro.csv', "r") as csv_file: + data = list(csv.reader(csv_file, delimiter=";")) + for row in data: + Sociopro.objects.create(code=row[0], name=row[1]) + end_time = timezone.now() + self.stdout.write( + self.style.SUCCESS( + f"Le chargement a pris: {(end_time-start_time).total_seconds()} seconds." + ) + ) diff --git a/inscription/models.py b/inscription/models.py index 974fd89..007f324 100644 --- a/inscription/models.py +++ b/inscription/models.py @@ -1,9 +1,31 @@ from django.db import models -from django_countries.fields import CountryField from address.models import AddressField +from phonenumber_field.modelfields import PhoneNumberField from .utils import nom_photo, create_hash +class Sociopro(models.Model): + """Base de donnée des codes socioprofessionnels. + Le données sont importées depuis le fichier CSV grâce à la commande python manage.py sociopro""" + code = models.CharField(max_length=4, verbose_name="Code Sociopro") + name = models.CharField(max_length=50, verbose_name="Catégorie sociopro") + + def __str__(self): + """Indique ce que donne l'affichage de la classe, notamment dans les menus déroulants""" + return u'%s' % self.name + + +class Pays(models.Model): + """Base de donnée des pays avec code INSEE. + Le données sont importées depuis le fichier CSV grâce à la commande python manage.py pays""" + code = models.CharField(max_length=4, verbose_name="Code INSEE") + name = models.CharField(max_length=50, verbose_name="Département") + + def __str__(self): + """Indique ce que donne l'affichage de la classe, notamment dans les menus déroulants""" + return u'%s' % (self.name) + + class Departement(models.Model): """Base de donnée des départements avec code INSEE. Le données sont importées depuis le fichier CSV grâce à la commande python manage.py departement""" @@ -42,47 +64,52 @@ def __iter__(self): ('MME', 'Mme') ) - STREET_TYPE_CHOICES = ( - ('Boulevard', 'Boulevard'), - ('Avenue', 'Avenue'), - ('Cours', 'Cours'), - ('Place', 'Place'), - ('Rue', 'Rue'), - ('Route', 'Route'), - ('Voie', 'Voie'), - ('Chemin', 'Chemin'), - ('Square', 'Square'), - ('Impasse', 'Impasse'), - ('Rond-point', 'Rond-point'), - ('Quai', 'Quai') + GENRE = ( + ('Il', 'Il'), + ('Elle', 'Elle'), + ('Iel', 'Iel') ) - + date_naissance = models.DateField(verbose_name="Date de naissance") commune_naissance = models.ForeignKey(Commune, on_delete=models.CASCADE, verbose_name="Commune de naissance") departement_naissance = models.ForeignKey(Departement, on_delete=models.CASCADE, verbose_name="Département de naissance") - address = AddressField(verbose_name="Adresse") + pays_naissance = models.ForeignKey(Pays, on_delete=models.CASCADE, verbose_name="Pays de naissance") + address = AddressField(verbose_name="Adresse", related_name='eleve') civility = models.CharField(max_length=3, choices=CIVILITY_CHOICES, default='M.', verbose_name="Civilité") - last_name = models.CharField(max_length=255, verbose_name="Nom de famille") - first_name = models.CharField(max_length=255, verbose_name="Prénom") - birth_date = models.DateField(verbose_name="Date de naissance") - birth_place = models.CharField(max_length=255, verbose_name="Ville de naissance") - birth_country = CountryField(max_length=255, verbose_name="Pays de naissance") - mail = models.EmailField(max_length=255, verbose_name="Mail") - street_type = models.CharField(max_length=30, verbose_name="Type de rue", - choices=STREET_TYPE_CHOICES, default='Rue') - street_number = models.CharField(max_length=30, verbose_name="Numéro de rue") - street = models.CharField(max_length=30, verbose_name="Rue") - comp_1 = models.CharField(max_length=255, verbose_name="Complément 1", - blank=True, null=True) - comp_2 = models.CharField(max_length=255, verbose_name="Complément 2", - blank=True, null=True) - city = models.CharField(max_length=255, verbose_name="Ville") - zip_code = models.CharField(max_length=255, verbose_name="Code postal") - country = CountryField(max_length=255, verbose_name="Pays") - phone = models.CharField(max_length=255, blank=True, null=True, - verbose_name="Téléphone") + genre = models.CharField(max_length=5, choices=GENRE, verbose_name='Pronom', default='Iel', + help_text="Veux-tu que l'on parle de toi en disant il, elle ou iel ?") + nom = models.CharField(max_length=255, verbose_name="Nom de famille") + prenom = models.CharField(max_length=255, verbose_name="Prénom") + nom_usage = models.CharField(max_length=255, verbose_name="Nom d'usage") + email = models.EmailField(max_length=255, verbose_name="Email") + telephone = models.CharField(max_length=255, blank=True, null=True, + verbose_name="Téléphone") comments = models.TextField(blank=True, null=True, verbose_name="Commentaires") hash = models.CharField(max_length=30, default=create_hash, unique=True) photo = models.ImageField(upload_to=nom_photo, null=True) - + # RESPONSABLES + RESP = ( + ('pere','Père'), + ('mere', 'Mère'), + ('autre', 'Autre responsable légal ou référent') + ) + resp2 = models.BooleanField(verbose_name="Deuxième responsable") + nom_resp1 = models.CharField(max_length=255, verbose_name="Nom de famille") + nom_resp2 = models.CharField(max_length=255, verbose_name="Nom de famille") + prenom_resp1 = models.CharField(max_length=255, verbose_name="Prénom") + prenom_resp2 = models.CharField(max_length=255, verbose_name="Prénom") + type_resp1 = models.CharField(max_length=5, choices=RESP, + default='mere', verbose_name="Lien de parenté") + type_resp2 = models.CharField(max_length=5, choices=RESP, + default='mere', verbose_name="Lien de parenté") + adresse_resp1 = AddressField(verbose_name="Adresse", related_name='rep1') + adresse_resp2 = AddressField(verbose_name="Adresse", related_name='rep2') + email_resp1 = models.EmailField(max_length=255, verbose_name="Email") + email_resp2 = models.EmailField(max_length=255, verbose_name="Email") + tel_resp1 = PhoneNumberField(verbose_name="Numéro de téléphone") + tel_resp2 = PhoneNumberField(verbose_name="Numéro de téléphone") + sociopro_resp1 = models.ForeignKey(Sociopro, related_name='rep1', + on_delete=models.CASCADE, verbose_name="Profession") + sociopro_resp2 = models.ForeignKey(Sociopro, related_name='resp2', + on_delete=models.CASCADE, verbose_name="Profession") diff --git a/inscription/utils.py b/inscription/utils.py index 4fb91cc..25e54f4 100644 --- a/inscription/utils.py +++ b/inscription/utils.py @@ -76,8 +76,8 @@ def nom_photo(instance, filename): upload_to = 'photos' ext = filename.split('.')[-1] # get filename - if instance.last_name and instance.first_name: - filename = '{}_{}.{}'.format(instance.last_name, instance.first_name, ext) + if instance.nom and instance.prenom: + filename = '{}_{}.{}'.format(instance.nom, instance.prenom, ext) else: # set filename as random string filename = '{}.{}'.format(uuid4().hex, ext) diff --git a/inscription/views.py b/inscription/views.py index 25faaba..204ea4e 100644 --- a/inscription/views.py +++ b/inscription/views.py @@ -18,7 +18,7 @@ from djangoLxp import settings from .filters import ListeEleveFiltre # Base BaseEleve -from .models import BaseEleve +from .models import BaseEleve, Pays # Tableau des inscrits from .tables import ListeEleveTableau # Une vue pour afficher les inscriptions filtées @@ -52,7 +52,7 @@ def fiche_pdf(request, **kwargs): response = HttpResponse(content_type="application/pdf") response['Content-Disposition'] = "inline; filename=fiche-{name}-{date}.pdf".format( date=timezone.now().strftime('%Y-%m-%d'), - name=slugify(eleve.first_name), + name=slugify(eleve.prenom), ) html = render_to_string("inscription/fiche_inscription.html", { 'fiche': eleve, @@ -125,12 +125,20 @@ def carto(request, **kwargs): return render(request, 'inscription/carto.html', {'adresses': coordonnees(BaseEleve.objects.all())}) -class Autocomplete(autocomplete.Select2QuerySetView): +class AutocompleteCommune(autocomplete.Select2QuerySetView): """Une vue pour permettre l'autocomplétion de recherche de commune par département.""" def get_queryset(self): - qs = super(Autocomplete, self).get_queryset() + qs = super(AutocompleteCommune, self).get_queryset() dep = self.forwarded.get('departement_naissance', None) if dep: qs = qs.filter(departement_id=dep) + return qs + + +class AutocompletePays(autocomplete.Select2QuerySetView): + def get_queryset(self): + qs = Pays.objects.all().order_by('name') + if self.q: + qs = qs.filter(name__istartswith=self.q) return qs \ No newline at end of file diff --git a/migrations/inscription/0001_initial.py b/migrations/inscription/0001_initial.py index 241dd9a..9018957 100644 --- a/migrations/inscription/0001_initial.py +++ b/migrations/inscription/0001_initial.py @@ -1,10 +1,10 @@ -# Generated by Django 4.0 on 2022-01-18 21:32 +# Generated by Django 4.0 on 2022-01-22 11:06 import address.models from django.db import migrations, models import django.db.models.deletion -import django_countries.fields import inscription.utils +import phonenumber_field.modelfields class Migration(migrations.Migration): @@ -24,6 +24,22 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=50, verbose_name='Département')), ], ), + migrations.CreateModel( + name='Pays', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=4, verbose_name='Code INSEE')), + ('name', models.CharField(max_length=50, verbose_name='Département')), + ], + ), + migrations.CreateModel( + name='Sociopro', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('code', models.CharField(max_length=4, verbose_name='Code Sociopro')), + ('name', models.CharField(max_length=50, verbose_name='Catégorie sociopro')), + ], + ), migrations.CreateModel( name='Commune', fields=[ @@ -37,28 +53,36 @@ class Migration(migrations.Migration): name='BaseEleve', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date_naissance', models.DateField(verbose_name='Date de naissance')), ('civility', models.CharField(choices=[('M.', 'M.'), ('MME', 'Mme')], default='M.', max_length=3, verbose_name='Civilité')), - ('last_name', models.CharField(max_length=255, verbose_name='Nom de famille')), - ('first_name', models.CharField(max_length=255, verbose_name='Prénom')), - ('birth_date', models.DateField(verbose_name='Date de naissance')), - ('birth_place', models.CharField(max_length=255, verbose_name='Ville de naissance')), - ('birth_country', django_countries.fields.CountryField(max_length=255, verbose_name='Pays de naissance')), - ('mail', models.EmailField(max_length=255, verbose_name='Mail')), - ('street_type', models.CharField(choices=[('Boulevard', 'Boulevard'), ('Avenue', 'Avenue'), ('Cours', 'Cours'), ('Place', 'Place'), ('Rue', 'Rue'), ('Route', 'Route'), ('Voie', 'Voie'), ('Chemin', 'Chemin'), ('Square', 'Square'), ('Impasse', 'Impasse'), ('Rond-point', 'Rond-point'), ('Quai', 'Quai')], default='Rue', max_length=30, verbose_name='Type de rue')), - ('street_number', models.CharField(max_length=30, verbose_name='Numéro de rue')), - ('street', models.CharField(max_length=30, verbose_name='Rue')), - ('comp_1', models.CharField(blank=True, max_length=255, null=True, verbose_name='Complément 1')), - ('comp_2', models.CharField(blank=True, max_length=255, null=True, verbose_name='Complément 2')), - ('city', models.CharField(max_length=255, verbose_name='Ville')), - ('zip_code', models.CharField(max_length=255, verbose_name='Code postal')), - ('country', django_countries.fields.CountryField(max_length=255, verbose_name='Pays')), - ('phone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Téléphone')), + ('genre', models.CharField(choices=[('Il', 'Il'), ('Elle', 'Elle'), ('Iel', 'Iel')], default='Iel', help_text="Veux-tu que l'on parle de toi en disant il, elle ou iel ?", max_length=5, verbose_name='Pronom')), + ('nom', models.CharField(max_length=255, verbose_name='Nom de famille')), + ('prenom', models.CharField(max_length=255, verbose_name='Prénom')), + ('nom_usage', models.CharField(max_length=255, verbose_name="Nom d'usage")), + ('email', models.EmailField(max_length=255, verbose_name='EMail')), + ('telephone', models.CharField(blank=True, max_length=255, null=True, verbose_name='Téléphone')), ('comments', models.TextField(blank=True, null=True, verbose_name='Commentaires')), ('hash', models.CharField(default=inscription.utils.create_hash, max_length=30, unique=True)), ('photo', models.ImageField(null=True, upload_to=inscription.utils.nom_photo)), - ('address', address.models.AddressField(on_delete=django.db.models.deletion.CASCADE, to='address.address', verbose_name='Adresse')), + ('resp2', models.BooleanField(verbose_name='Deuxième responsable')), + ('nom_resp1', models.CharField(max_length=255, verbose_name='Nom de famille')), + ('nom_resp2', models.CharField(max_length=255, verbose_name='Nom de famille')), + ('prenom_resp1', models.CharField(max_length=255, verbose_name='Prénom')), + ('prenom_resp2', models.CharField(max_length=255, verbose_name='Prénom')), + ('type_resp1', models.CharField(choices=[('pere', 'Père'), ('mere', 'Mère'), ('autre', 'Autre responsable légal ou référent')], default='mere', max_length=5, verbose_name='Type')), + ('type_resp2', models.CharField(choices=[('pere', 'Père'), ('mere', 'Mère'), ('autre', 'Autre responsable légal ou référent')], default='mere', max_length=5, verbose_name='Type')), + ('email_resp1', models.EmailField(max_length=255, verbose_name='EMail')), + ('email_resp2', models.EmailField(max_length=255, verbose_name='EMail')), + ('tel_resp1', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None, verbose_name='Numéro de téléphone')), + ('tel_resp2', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region=None, verbose_name='Numéro de téléphone')), + ('address', address.models.AddressField(on_delete=django.db.models.deletion.CASCADE, related_name='eleve', to='address.address', verbose_name='Adresse')), + ('adresse_resp1', address.models.AddressField(on_delete=django.db.models.deletion.CASCADE, related_name='rep1', to='address.address', verbose_name='Adresse')), + ('adresse_resp2', address.models.AddressField(on_delete=django.db.models.deletion.CASCADE, related_name='rep2', to='address.address', verbose_name='Adresse')), ('commune_naissance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inscription.commune', verbose_name='Commune de naissance')), ('departement_naissance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inscription.departement', verbose_name='Département de naissance')), + ('pays_naissance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inscription.pays', verbose_name='Pays de naissance')), + ('sociopro_resp1', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rep1', to='inscription.sociopro', verbose_name='Profession')), + ('sociopro_resp2', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resp2', to='inscription.sociopro', verbose_name='Profession')), ], ), ] diff --git a/requirements.txt b/requirements.txt index 2876e4b..f14bcfb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,8 +10,8 @@ charset-normalizer==2.0.9 cssselect2==0.4.1 dj-database-url==0.5.0 Django==4.0 -git+https://github.com/yourlabs/django-autocomplete-light@dj4#egg=django-autocomplete-light django-address==0.2.5 +git+https://github.com/yourlabs/django-autocomplete-light@dj4#egg=django-autocomplete-light django-bootstrap4==21.1 django-brotli==0.2.0 django-countries==7.2.1 @@ -20,6 +20,7 @@ django-filter==21.1 django-formtools==2.3 django-heroku==0.0.0 django-leaflet==0.28.2 +django-phonenumber-field[phonenumberslite]==6.0.0 django-ranged-response==0.2.0 django-simple-captcha==0.5.14 django-storages==1.12.3 @@ -31,6 +32,7 @@ gunicorn==20.1.0 html5lib==1.1 idna==3.3 jmespath==0.10.0 +phonenumberslite==8.12.41 Pillow==8.4.0 pipreqs==0.4.11 psycopg2-binary==2.9.2 diff --git a/templates/inscription/fiche_inscription.html b/templates/inscription/fiche_inscription.html index 86c547d..a62ebac 100644 --- a/templates/inscription/fiche_inscription.html +++ b/templates/inscription/fiche_inscription.html @@ -19,7 +19,7 @@

Fiche d'inscription

Année 2022 {# NOM PRENOM #}
-

{{ fiche.first_name }} {{ fiche.last_name }}

+

{{ fiche.prenom }} {{ fiche.nom }}

{{ fiche.address }}
From 6936693919c72be3297e84bf00a9fee18717ff02 Mon Sep 17 00:00:00 2001 From: Davy39 Date: Sat, 22 Jan 2022 12:44:16 +0100 Subject: [PATCH 2/2] Modif app.json pour Heroku --- app.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.json b/app.json index 02533af..8925839 100644 --- a/app.json +++ b/app.json @@ -5,6 +5,6 @@ }, { "url": "https://github.com/heroku/heroku-geo-buildpack" - }, + } ] } \ No newline at end of file