From 669129e30d5c5ae1824fe66461222d350f50a152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 20 Feb 2017 01:12:06 +0100 Subject: [PATCH 01/18] Move the club model to the gestion app - Move the model - Add some BDS-related fields - Add an `associations` fields to be able to separate the clubs between the different associations using groups --- cof/migrations/0012_remove_club.py | 23 ++++++ cof/models.py | 12 ---- gestion/migrations/0002_club_support.py | 95 +++++++++++++++++++++++++ gestion/models.py | 54 +++++++++++++- 4 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 cof/migrations/0012_remove_club.py create mode 100644 gestion/migrations/0002_club_support.py diff --git a/cof/migrations/0012_remove_club.py b/cof/migrations/0012_remove_club.py new file mode 100644 index 00000000..ebc48d37 --- /dev/null +++ b/cof/migrations/0012_remove_club.py @@ -0,0 +1,23 @@ +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cof', '0011_delete_clipper_and_custommail'), + ('gestion', '0002_club_support') + ] + + operations = [ + migrations.RemoveField( + model_name='club', + name='membres', + ), + migrations.RemoveField( + model_name='club', + name='respos', + ), + migrations.DeleteModel( + name='Club', + ), + ] diff --git a/cof/models.py b/cof/models.py index dafe9996..1d1f5b07 100644 --- a/cof/models.py +++ b/cof/models.py @@ -79,18 +79,6 @@ class CofProfile(models.Model): return self.profile.user.username -@python_2_unicode_compatible -class Club(models.Model): - name = models.CharField("Nom", max_length=200, unique=True) - description = models.TextField("Description", blank=True) - respos = models.ManyToManyField(User, related_name="clubs_geres", - blank=True) - membres = models.ManyToManyField(User, related_name="clubs", blank=True) - - def __str__(self): - return self.name - - @python_2_unicode_compatible class Event(models.Model): title = models.CharField("Titre", max_length=200) diff --git a/gestion/migrations/0002_club_support.py b/gestion/migrations/0002_club_support.py new file mode 100644 index 00000000..6b23882b --- /dev/null +++ b/gestion/migrations/0002_club_support.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from django.conf import settings + + +def keep_cof_clubs(apps, schema_editor): + Group = apps.get_model("auth", "Group") + CofClub = apps.get_model("cof", "Club") + NewClub = apps.get_model("gestion", "Club") + Registration = apps.get_model("gestion", "ClubUser") + + cof_group = Group.objects.get(name="cof_members") + + for oldclub in CofClub.objects.all(): + newclub = NewClub.objects.create( + name=oldclub.name, + description=oldclub.description, + ) + for user in oldclub.membres.all(): + Registration.objects.create( + club=newclub, + user=user, + has_paid=True + ) + for user in oldclub.respos.all(): + reg = Registration.objects.get_or_create( + user=user, + club=newclub + ) + reg.is_respo = True + reg.save() + newclub.associations.add(cof_group) + newclub.save() + + +def restore_cof_clubs(apps, schema_editor): + Group = apps.get_model("auth", "Group") + Club = apps.get_model("cof", "Club") + Registration = apps.get_model("gestion", "ClubUser") + + cof_group = Group.objects.get(name="cof_members") + + for newclub in cof_group.clubs.all(): + club = Club.objects.create( + name=newclub.name, + description=newclub.description + ) + for reg in Registration.objects.filter(club=newclub): + if reg.is_respo: + club.respos.add(reg.user) + else: + club.membres.add(reg.user) + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0006_require_contenttypes_0002'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cof', '0011_delete_clipper_and_custommail'), + ('gestion', '0001_initial'), + ] + + operations = [ + migrations.RunPython(lambda: 1/0), + migrations.CreateModel( + name='Club', + fields=[ + ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), + ('name', models.CharField(unique=True, max_length=200, verbose_name='Nom')), + ('description', models.TextField(verbose_name='Description', blank=True)), + ('price', models.DecimalField(verbose_name='Cotisation (€)', decimal_places=2, default=0, blank=True, max_digits=5)), + ('cotisation_frequency', models.CharField(choices=[('ANN', 'Annuel'), ('SEM', 'Semestriel'), ('COU', 'Au cours')], max_length=3, verbose_name='Fréquence de la cotisation', default='ANN', blank=True)), + ('associations', models.ManyToManyField(to='auth.Group', related_name='clubs')), + ], + ), + migrations.CreateModel( + name='ClubUser', + fields=[ + ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), + ('is_respo', models.BooleanField(verbose_name='Est responsable du club')), + ('has_paid', models.BooleanField(verbose_name='A payé sa cotisation')), + ('club', models.ForeignKey(to='gestion.Club')), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.AddField( + model_name='club', + name='members', + field=models.ManyToManyField(to=settings.AUTH_USER_MODEL, related_name='in_clubs', through='gestion.ClubUser', blank=True), + ), + migrations.RunPython(keep_cof_clubs, restore_cof_clubs), + ] diff --git a/gestion/models.py b/gestion/models.py index 81335ddc..98c06d0e 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -1,4 +1,4 @@ -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Group from django.db import models from django.dispatch import receiver from django.db.models.signals import post_save, post_delete @@ -17,6 +17,7 @@ OCCUPATION_CHOICES = ( ('CST', _("CST")), ) + class Profile(models.Model): user = models.OneToOneField(User, related_name="profile") @@ -39,6 +40,7 @@ class Profile(models.Model): def __str__(self): return self.user.username + @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: @@ -48,3 +50,53 @@ def create_user_profile(sender, instance, created, **kwargs): @receiver(post_delete, sender=Profile) def post_delete_user(sender, instance, *args, **kwargs): instance.user.delete() + + +class Club(models.Model): + ANNUAL = "ANN" + SEMESTER = "SEM" + COURSE = "COU" + + COTISATION_FREQUENCY_CHOICES = [ + (ANNUAL, _("Annuel")), + (SEMESTER, _("Semestriel")), + (COURSE, _("Au cours")) + ] + + associations = models.ManyToManyField(Group, related_name="clubs") + name = models.CharField(_("Nom"), max_length=200, unique=True) + description = models.TextField("Description", blank=True) + members = models.ManyToManyField( + User, + through="ClubUser", + related_name="in_clubs", + blank=True + ) + price = models.DecimalField( + _("Cotisation (€)"), + decimal_places=2, + max_digits=5, + blank=True, + default=0 + ) + cotisation_frequency = models.CharField( + _("Fréquence de la cotisation"), + default=ANNUAL, + choices=COTISATION_FREQUENCY_CHOICES, + max_length=3, + blank=True + ) + + def __str__(self): + template = ( + self.price and "{name} ({price}€ / {cotisation_frequency})" + or "{name}" + ) + return template.format(**vars(self)) + + +class ClubUser(models.Model): + user = models.ForeignKey(User) + club = models.ForeignKey(Club) + is_respo = models.BooleanField(_("Est responsable du club")) + has_paid = models.BooleanField(_("A payé sa cotisation")) From 1f85f7589663a650e1337d803086a053b9919d35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Mon, 20 Feb 2017 01:16:50 +0100 Subject: [PATCH 02/18] Include the Clubs into the admin site --- cof/admin.py | 22 +--------------------- gestion/admin.py | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/cof/admin.py b/cof/admin.py index 177a5adf..227cfb55 100644 --- a/cof/admin.py +++ b/cof/admin.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -from django import forms from django.contrib import admin from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe @@ -13,7 +12,7 @@ from .petits_cours_models import PetitCoursDemande, \ PetitCoursAttributionCounter from .models import ( SurveyQuestionAnswer, SurveyQuestion, CofProfile, EventOption, - EventOptionChoice, Event, Club, EventCommentField, EventRegistration, + EventOptionChoice, Event, EventCommentField, EventRegistration, Survey ) @@ -135,30 +134,11 @@ class PetitCoursDemandeAdmin(admin.ModelAdmin): search_fields = ('name', 'email', 'phone', 'lieu', 'remarques') -class ClubAdminForm(forms.ModelForm): - def clean(self): - cleaned_data = super(ClubAdminForm, self).clean() - respos = cleaned_data.get('respos') - members = cleaned_data.get('membres') - for respo in respos.all(): - if respo not in members: - raise forms.ValidationError( - "Erreur : le respo %s n'est pas membre du club." - % respo.get_full_name()) - return cleaned_data - - -class ClubAdmin(admin.ModelAdmin): - list_display = ['name'] - form = ClubAdminForm - - admin.site.register(Survey, SurveyAdmin) admin.site.register(SurveyQuestion, SurveyQuestionAdmin) admin.site.register(Event, EventAdmin) admin.site.register(EventOption, EventOptionAdmin) admin.site.register(CofProfile) -admin.site.register(Club, ClubAdmin) admin.site.register(PetitCoursSubject) admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin) admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin) diff --git a/gestion/admin.py b/gestion/admin.py index 52e3cb55..a25c618d 100644 --- a/gestion/admin.py +++ b/gestion/admin.py @@ -2,9 +2,13 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.models import User -from .models import Profile +from .models import Profile, Club +# --- +# The user related stuff +# --- + class ProfileInline(admin.StackedInline): model = Profile inline_classes = ["collapse open"] @@ -16,5 +20,14 @@ class UserProfileAdmin(UserAdmin): ] +# --- +# Clubs +# --- + +@admin.register(Club) +class ClubAdmin(admin.ModelAdmin): + pass + + admin.site.unregister(User) admin.site.register(User, UserProfileAdmin) From f8a8465630fadacabae69bffd409a267293a5205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 15:23:37 +0100 Subject: [PATCH 03/18] Remove useless imports --- gestion/urls.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gestion/urls.py b/gestion/urls.py index 55e5658a..0e7d63ac 100644 --- a/gestion/urls.py +++ b/gestion/urls.py @@ -1,7 +1,6 @@ -from django.conf.urls import url, include +from django.conf.urls import url from django.views.generic.base import TemplateView from django.contrib.auth import views as django_views -from django.contrib import admin from django_cas_ng import views as django_cas_views from . import views From d36d69238d4296b9efe6d3f068ed2693ea434aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 18:19:49 +0100 Subject: [PATCH 04/18] Add groups and permissions for BDS staff & members --- bds/migrations/0002_add_BDS_groups.py | 52 +++++++++++++++++++++++++++ bds/models.py | 8 +++++ 2 files changed, 60 insertions(+) create mode 100644 bds/migrations/0002_add_BDS_groups.py diff --git a/bds/migrations/0002_add_BDS_groups.py b/bds/migrations/0002_add_BDS_groups.py new file mode 100644 index 00000000..f0b4a75c --- /dev/null +++ b/bds/migrations/0002_add_BDS_groups.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib.auth.models import Group, Permission +from django.db import migrations + + +def create_groups(apps, schema_editor): + from django.contrib.auth.management import create_permissions + + apps.models_module = True + create_permissions(apps, verbosity=0) + apps.models_module = None + + memberp = Permission.objects.get( + codename="member", + content_type__app_label="bds" + ) + burop = Permission.objects.get( + codename="buro", + content_type__app_label="bds" + ) + + # Creates the groups for BDS members and staff + member = Group.objects.create(name="bds_members") + buro = Group.objects.create(name="bds_buro") + + # Associates the permissions to the respective groups + member.permissions = [memberp] + buro.permissions = [memberp, burop] + + +class Migration(migrations.Migration): + + dependencies = [ + ('bds', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='bdsprofile', + options={ + 'permissions': [ + ('member', 'Is a BDS member'), + ('buro', 'Is part of the BDS staff') + ], + 'verbose_name': 'Profil BDS', + 'verbose_name_plural': 'Profils BDS' + }, + ), + migrations.RunPython(create_groups, migrations.RunPython.noop), + ] diff --git a/bds/models.py b/bds/models.py index ecfbb3db..da80dd77 100644 --- a/bds/models.py +++ b/bds/models.py @@ -55,3 +55,11 @@ class BdsProfile(models.Model): default='CASH', choices=PAYMENT_METHOD_CHOICES, max_length=6) + + class Meta: + verbose_name = "Profil BDS" + verbose_name_plural = "Profils BDS" + permissions = [ + ("member", "Is a BDS member"), + ("buro", "Is part of the BDS staff") + ] From c81b84978566c3b06135cc4719ab9d81304333e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 18:21:23 +0100 Subject: [PATCH 05/18] Prevent conflicts in COF perm migration There may be a conflict during the migration cof 0009 if the permissions are referenced only by their codename. --- cof/migrations/0009_generic_profiles.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cof/migrations/0009_generic_profiles.py b/cof/migrations/0009_generic_profiles.py index 673202b8..a544ce74 100644 --- a/cof/migrations/0009_generic_profiles.py +++ b/cof/migrations/0009_generic_profiles.py @@ -30,8 +30,14 @@ def preserve_perms(apps, schema_editor): apps.models_module = None CofProfile = apps.get_model("cof", "CofProfile") - memberp = Permission.objects.get(codename='member') - burop = Permission.objects.get(codename='buro') + memberp = Permission.objects.get( + codename='member', + content_type__app_label="cof" + ) + burop = Permission.objects.get( + codename='buro', + content_type__app_label="cof" + ) # creates the groups for COF members and member = Group.objects.create(name='cof_members') From 9f401b66e93a937c0986152af027e6f43b29906d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 19:28:34 +0100 Subject: [PATCH 06/18] Specify the on_delete attribute everywhere - Models - Migrations --- bda/migrations/0001_initial.py | 26 +++++-- bda/migrations/0002_add_tirage.py | 14 +++- bda/migrations/0007_extends_spectacle.py | 11 ++- bda/migrations/0009_revente.py | 23 ++++-- bda/models.py | 65 +++++++++++----- bds/migrations/0001_initial.py | 5 +- cof/migrations/0001_initial.py | 94 +++++++++++++++++++----- cof/migrations/0006_add_calendar.py | 4 +- cof/migrations/0009_generic_profiles.py | 18 +++-- cof/models.py | 68 +++++++++++++---- cof/petits_cours_models.py | 45 ++++++++++-- gestion/migrations/0001_initial.py | 5 +- gestion/models.py | 9 ++- kfet/migrations/0048_generic_profiles.py | 5 +- 14 files changed, 299 insertions(+), 93 deletions(-) diff --git a/bda/migrations/0001_initial.py b/bda/migrations/0001_initial.py index aa2cb252..da447b9d 100644 --- a/bda/migrations/0001_initial.py +++ b/bda/migrations/0001_initial.py @@ -59,7 +59,9 @@ class Migration(migrations.Migration): ('price', models.FloatField(verbose_name=b"Prix d'une place", blank=True)), ('slots', models.IntegerField(verbose_name=b'Places')), ('priority', models.IntegerField(default=1000, verbose_name=b'Priorit\xc3\xa9')), - ('location', models.ForeignKey(to='bda.Salle')), + ('location', models.ForeignKey( + on_delete=models.CASCADE, + to='bda.Salle')), ], options={ 'ordering': ('priority', 'date', 'title'), @@ -79,27 +81,39 @@ class Migration(migrations.Migration): migrations.AddField( model_name='participant', name='user', - field=models.OneToOneField(to=settings.AUTH_USER_MODEL), + field=models.OneToOneField( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='choixspectacle', name='participant', - field=models.ForeignKey(to='bda.Participant'), + field=models.ForeignKey( + on_delete=models.CASCADE, + to='bda.Participant'), ), migrations.AddField( model_name='choixspectacle', name='spectacle', - field=models.ForeignKey(related_name='participants', to='bda.Spectacle'), + field=models.ForeignKey( + on_delete=models.CASCADE, + related_name='participants', + to='bda.Spectacle'), ), migrations.AddField( model_name='attribution', name='participant', - field=models.ForeignKey(to='bda.Participant'), + field=models.ForeignKey( + on_delete=models.CASCADE, + to='bda.Participant'), ), migrations.AddField( model_name='attribution', name='spectacle', - field=models.ForeignKey(related_name='attribues', to='bda.Spectacle'), + field=models.ForeignKey( + related_name='attribues', + on_delete=models.CASCADE, + to='bda.Spectacle'), ), migrations.AlterUniqueTogether( name='choixspectacle', diff --git a/bda/migrations/0002_add_tirage.py b/bda/migrations/0002_add_tirage.py index 1956a4a4..3b5c5a0b 100644 --- a/bda/migrations/0002_add_tirage.py +++ b/bda/migrations/0002_add_tirage.py @@ -39,18 +39,26 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='participant', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='participant', name='tirage', - field=models.ForeignKey(default=1, to='bda.Tirage'), + field=models.ForeignKey( + on_delete=models.CASCADE, + default=1, + to='bda.Tirage'), preserve_default=False, ), migrations.AddField( model_name='spectacle', name='tirage', - field=models.ForeignKey(default=1, to='bda.Tirage'), + field=models.ForeignKey( + on_delete=models.CASCADE, + default=1, + to='bda.Tirage'), preserve_default=False, ), ] diff --git a/bda/migrations/0007_extends_spectacle.py b/bda/migrations/0007_extends_spectacle.py index b95c18de..f6e1834f 100644 --- a/bda/migrations/0007_extends_spectacle.py +++ b/bda/migrations/0007_extends_spectacle.py @@ -72,8 +72,11 @@ class Migration(migrations.Migration): migrations.AddField( model_name='spectacle', name='category', - field=models.ForeignKey(blank=True, to='bda.CategorieSpectacle', - null=True), + field=models.ForeignKey( + on_delete=models.CASCADE, + blank=True, + to='bda.CategorieSpectacle', + null=True), ), migrations.AddField( model_name='spectacle', @@ -84,6 +87,8 @@ class Migration(migrations.Migration): migrations.AddField( model_name='quote', name='spectacle', - field=models.ForeignKey(to='bda.Spectacle'), + field=models.ForeignKey( + on_delete=models.CASCADE, + to='bda.Spectacle'), ), ] diff --git a/bda/migrations/0009_revente.py b/bda/migrations/0009_revente.py index 1cca4e86..223a2ed7 100644 --- a/bda/migrations/0009_revente.py +++ b/bda/migrations/0009_revente.py @@ -46,21 +46,28 @@ class Migration(migrations.Migration): migrations.AddField( model_name='spectaclerevente', name='attribution', - field=models.OneToOneField(to='bda.Attribution', - related_name='revente'), + field=models.OneToOneField( + to='bda.Attribution', + on_delete=models.CASCADE, + related_name='revente'), ), migrations.AddField( model_name='spectaclerevente', name='seller', - field=models.ForeignKey(to='bda.Participant', - verbose_name='Vendeur', - related_name='original_shows'), + field=models.ForeignKey( + on_delete=models.CASCADE, + to='bda.Participant', + verbose_name='Vendeur', + related_name='original_shows'), ), migrations.AddField( model_name='spectaclerevente', name='soldTo', - field=models.ForeignKey(to='bda.Participant', - verbose_name='Vendue à', null=True, - blank=True), + field=models.ForeignKey( + on_delete=models.CASCADE, + to='bda.Participant', + verbose_name='Vendue à', + null=True, + blank=True), ), ] diff --git a/bda/models.py b/bda/models.py index a405a665..008f55f5 100644 --- a/bda/models.py +++ b/bda/models.py @@ -46,9 +46,14 @@ class CategorieSpectacle(models.Model): class Spectacle(models.Model): title = models.CharField("Titre", max_length=300) - category = models.ForeignKey(CategorieSpectacle, blank=True, null=True) + category = models.ForeignKey( + CategorieSpectacle, + on_delete=models.CASCADE, + blank=True, + null=True + ) date = models.DateTimeField("Date & heure") - location = models.ForeignKey(Salle) + location = models.ForeignKey(Salle, on_delete=models.CASCADE) vips = models.TextField('Personnalités', blank=True) description = models.TextField("Description", blank=True) slots_description = models.TextField("Description des places", blank=True) @@ -58,7 +63,7 @@ class Spectacle(models.Model): max_length=500) price = models.FloatField("Prix d'une place") slots = models.IntegerField("Places") - tirage = models.ForeignKey(Tirage) + tirage = models.ForeignKey(Tirage, on_delete=models.CASCADE) listing = models.BooleanField("Les places sont sur listing") rappel_sent = models.DateTimeField("Mail de rappel envoyé", blank=True, null=True) @@ -116,7 +121,7 @@ class Spectacle(models.Model): class Quote(models.Model): - spectacle = models.ForeignKey(Spectacle) + spectacle = models.ForeignKey(Spectacle, on_delete=models.CASCADE) text = models.TextField('Citation') author = models.CharField('Auteur', max_length=200) @@ -130,7 +135,7 @@ PAYMENT_TYPES = ( class Participant(models.Model): - user = models.ForeignKey(User) + user = models.ForeignKey(User, on_delete=models.CASCADE) choices = models.ManyToManyField(Spectacle, through="ChoixSpectacle", related_name="chosen_by") @@ -141,7 +146,7 @@ class Participant(models.Model): paymenttype = models.CharField("Moyen de paiement", max_length=6, choices=PAYMENT_TYPES, blank=True) - tirage = models.ForeignKey(Tirage) + tirage = models.ForeignKey(Tirage, on_delete=models.CASCADE) choicesrevente = models.ManyToManyField(Spectacle, related_name="subscribed", blank=True) @@ -157,8 +162,15 @@ DOUBLE_CHOICES = ( class ChoixSpectacle(models.Model): - participant = models.ForeignKey(Participant) - spectacle = models.ForeignKey(Spectacle, related_name="participants") + participant = models.ForeignKey( + Participant, + on_delete=models.CASCADE + ) + spectacle = models.ForeignKey( + Spectacle, + on_delete=models.CASCADE, + related_name="participants" + ) priority = models.PositiveIntegerField("Priorité") double_choice = models.CharField("Nombre de places", default="1", choices=DOUBLE_CHOICES, @@ -185,8 +197,15 @@ class ChoixSpectacle(models.Model): class Attribution(models.Model): - participant = models.ForeignKey(Participant) - spectacle = models.ForeignKey(Spectacle, related_name="attribues") + participant = models.ForeignKey( + Participant, + on_delete=models.CASCADE + ) + spectacle = models.ForeignKey( + Spectacle, + on_delete=models.CASCADE, + related_name="attribues" + ) given = models.BooleanField("Donnée", default=False) def __str__(self): @@ -195,19 +214,29 @@ class Attribution(models.Model): class SpectacleRevente(models.Model): - attribution = models.OneToOneField(Attribution, - related_name="revente") + attribution = models.OneToOneField( + Attribution, + on_delete=models.CASCADE, + related_name="revente" + ) date = models.DateTimeField("Date de mise en vente", default=timezone.now) answered_mail = models.ManyToManyField(Participant, related_name="wanted", blank=True) - seller = models.ForeignKey(Participant, - related_name="original_shows", - verbose_name="Vendeur") - soldTo = models.ForeignKey(Participant, blank=True, null=True, - verbose_name="Vendue à") - + seller = models.ForeignKey( + Participant, + on_delete=models.CASCADE, + related_name="original_shows", + verbose_name="Vendeur" + ) + soldTo = models.ForeignKey( + Participant, + on_delete=models.CASCADE, + blank=True, + null=True, + verbose_name="Vendue à" + ) notif_sent = models.BooleanField("Notification envoyée", default=False) tirage_done = models.BooleanField("Tirage effectué", diff --git a/bds/migrations/0001_initial.py b/bds/migrations/0001_initial.py index e0d3ddd9..3d6f5218 100644 --- a/bds/migrations/0001_initial.py +++ b/bds/migrations/0001_initial.py @@ -23,7 +23,10 @@ class Migration(migrations.Migration): ('cotisation_period', models.CharField(choices=[('ANN', 'Année'), ('SE1', 'Premier semestre'), ('SE2', 'Deuxième semestre')], verbose_name='Inscription', max_length=3, default='ANN')), ('registration_date', models.DateField(verbose_name="Date d'inscription", auto_now_add=True)), ('payment_method', models.CharField(choices=[('CASH', 'Liquide'), ('BANK', 'Transfer bancaire'), ('CHEQUE', 'Cheque'), ('OTHER', 'Autre')], verbose_name='Methode de paiement', max_length=6, default='CASH')), - ('profile', models.OneToOneField(related_name='bds', to='gestion.Profile')), + ('profile', models.OneToOneField( + related_name='bds', + on_delete=models.CASCADE, + to='gestion.Profile')), ], ), ] diff --git a/cof/migrations/0001_initial.py b/cof/migrations/0001_initial.py index 0540e689..fdfeaed4 100644 --- a/cof/migrations/0001_initial.py +++ b/cof/migrations/0001_initial.py @@ -48,7 +48,10 @@ class Migration(migrations.Migration): ('is_buro', models.BooleanField(default=False, verbose_name=b'Membre du Bur\xc3\xb4')), ('petits_cours_accept', models.BooleanField(default=False, verbose_name=b'Recevoir des petits cours')), ('petits_cours_remarques', models.TextField(default=b'', verbose_name='Remarques et pr\xe9cisions pour les petits cours', blank=True)), - ('user', models.OneToOneField(related_name='profile', to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField( + related_name='profile', + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL)), ], options={ 'verbose_name': 'Profil COF', @@ -91,7 +94,10 @@ class Migration(migrations.Migration): ('name', models.CharField(max_length=200, verbose_name=b'Champ')), ('fieldtype', models.CharField(default=b'text', max_length=10, verbose_name=b'Type', choices=[(b'text', 'Texte long'), (b'char', 'Texte court')])), ('default', models.TextField(verbose_name=b'Valeur par d\xc3\xa9faut', blank=True)), - ('event', models.ForeignKey(related_name='commentfields', to='cof.Event')), + ('event', models.ForeignKey( + related_name='commentfields', + on_delete=models.CASCADE, + to='cof.Event')), ], options={ 'verbose_name': 'Champ', @@ -102,7 +108,10 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('content', models.TextField(null=True, verbose_name=b'Contenu', blank=True)), - ('commentfield', models.ForeignKey(related_name='values', to='cof.EventCommentField')), + ('commentfield', models.ForeignKey( + related_name='values', + on_delete=models.CASCADE, + to='cof.EventCommentField')), ], ), migrations.CreateModel( @@ -111,7 +120,10 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('name', models.CharField(max_length=200, verbose_name=b'Option')), ('multi_choices', models.BooleanField(default=False, verbose_name=b'Choix multiples')), - ('event', models.ForeignKey(related_name='options', to='cof.Event')), + ('event', models.ForeignKey( + related_name='options', + on_delete=models.CASCADE, + to='cof.Event')), ], options={ 'verbose_name': 'Option', @@ -122,7 +134,10 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('value', models.CharField(max_length=200, verbose_name=b'Valeur')), - ('event_option', models.ForeignKey(related_name='choices', to='cof.EventOption')), + ('event_option', models.ForeignKey( + related_name='choices', + on_delete=models.CASCADE, + to='cof.EventOption')), ], options={ 'verbose_name': 'Choix', @@ -133,10 +148,14 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('paid', models.BooleanField(default=False, verbose_name=b'A pay\xc3\xa9')), - ('event', models.ForeignKey(to='cof.Event')), + ('event', models.ForeignKey( + on_delete=models.CASCADE, + to='cof.Event')), ('filledcomments', models.ManyToManyField(to='cof.EventCommentField', through='cof.EventCommentValue')), ('options', models.ManyToManyField(to='cof.EventOptionChoice')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL)), ], options={ 'verbose_name': 'Inscription', @@ -240,7 +259,10 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('question', models.CharField(max_length=200, verbose_name=b'Question')), ('multi_answers', models.BooleanField(default=False, verbose_name=b'Choix multiples')), - ('survey', models.ForeignKey(related_name='questions', to='cof.Survey')), + ('survey', models.ForeignKey( + on_delete=models.CASCADE, + related_name='questions', + to='cof.Survey')), ], options={ 'verbose_name': 'Question', @@ -251,7 +273,10 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('answer', models.CharField(max_length=200, verbose_name=b'R\xc3\xa9ponse')), - ('survey_question', models.ForeignKey(related_name='answers', to='cof.SurveyQuestion')), + ('survey_question', models.ForeignKey( + related_name='answers', + on_delete=models.CASCADE, + to='cof.SurveyQuestion')), ], options={ 'verbose_name': 'R\xe9ponse', @@ -265,12 +290,16 @@ class Migration(migrations.Migration): migrations.AddField( model_name='surveyanswer', name='survey', - field=models.ForeignKey(to='cof.Survey'), + field=models.ForeignKey( + on_delete=models.CASCADE, + to='cof.Survey'), ), migrations.AddField( model_name='surveyanswer', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='petitcoursdemande', @@ -280,47 +309,72 @@ class Migration(migrations.Migration): migrations.AddField( model_name='petitcoursdemande', name='traitee_par', - field=models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True), + field=models.ForeignKey( + on_delete=models.CASCADE, + blank=True, + to=settings.AUTH_USER_MODEL, + null=True), ), migrations.AddField( model_name='petitcoursattributioncounter', name='matiere', - field=models.ForeignKey(verbose_name='Matiere', to='cof.PetitCoursSubject'), + field=models.ForeignKey( + on_delete=models.CASCADE, + verbose_name='Matiere', + to='cof.PetitCoursSubject'), ), migrations.AddField( model_name='petitcoursattributioncounter', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='petitcoursattribution', name='demande', - field=models.ForeignKey(verbose_name='Demande', to='cof.PetitCoursDemande'), + field=models.ForeignKey( + on_delete=models.CASCADE, + verbose_name='Demande', + to='cof.PetitCoursDemande'), ), migrations.AddField( model_name='petitcoursattribution', name='matiere', - field=models.ForeignKey(verbose_name='Mati\xe8re', to='cof.PetitCoursSubject'), + field=models.ForeignKey( + on_delete=models.CASCADE, + verbose_name='Mati\xe8re', + to='cof.PetitCoursSubject'), ), migrations.AddField( model_name='petitcoursattribution', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='petitcoursability', name='matiere', - field=models.ForeignKey(verbose_name='Mati\xe8re', to='cof.PetitCoursSubject'), + field=models.ForeignKey( + on_delete=models.CASCADE, + verbose_name='Mati\xe8re', + to='cof.PetitCoursSubject'), ), migrations.AddField( model_name='petitcoursability', name='user', - field=models.ForeignKey(to=settings.AUTH_USER_MODEL), + field=models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='eventcommentvalue', name='registration', - field=models.ForeignKey(related_name='comments', to='cof.EventRegistration'), + field=models.ForeignKey( + on_delete=models.CASCADE, + related_name='comments', + to='cof.EventRegistration'), ), migrations.AlterUniqueTogether( name='surveyanswer', diff --git a/cof/migrations/0006_add_calendar.py b/cof/migrations/0006_add_calendar.py index 3009ac4d..f40ad39f 100644 --- a/cof/migrations/0006_add_calendar.py +++ b/cof/migrations/0006_add_calendar.py @@ -23,7 +23,9 @@ class Migration(migrations.Migration): ('subscribe_to_events', models.BooleanField(default=True)), ('subscribe_to_my_shows', models.BooleanField(default=True)), ('other_shows', models.ManyToManyField(to='bda.Spectacle')), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), + ('user', models.OneToOneField( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL)), ], ), migrations.AlterModelOptions( diff --git a/cof/migrations/0009_generic_profiles.py b/cof/migrations/0009_generic_profiles.py index 673202b8..ebbba4ae 100644 --- a/cof/migrations/0009_generic_profiles.py +++ b/cof/migrations/0009_generic_profiles.py @@ -23,23 +23,23 @@ def create_profile(apps, schema_editor): def preserve_perms(apps, schema_editor): - from django.contrib.auth.management import create_permissions + # from django.contrib.auth.management import create_permissions - apps.models_module = True - create_permissions(apps, verbosity=0) - apps.models_module = None + # apps.models_module = True + # create_permissions(apps, verbosity=0) + # apps.models_module = None CofProfile = apps.get_model("cof", "CofProfile") - memberp = Permission.objects.get(codename='member') - burop = Permission.objects.get(codename='buro') + # memberp = Permission.objects.get(codename='member') + # burop = Permission.objects.get(codename='buro') # creates the groups for COF members and member = Group.objects.create(name='cof_members') buro = Group.objects.create(name='cof_buro') # associate permissions to the respective groups. - buro.permissions = [burop, memberp] - member.permissions = [memberp] + # buro.permissions = [burop, memberp] + # member.permissions = [memberp] for cofp in CofProfile.objects.filter(is_cof=True): cofp.profile.user.groups.add(member) @@ -70,6 +70,7 @@ class Migration(migrations.Migration): model_name='cofprofile', name='profile', field=models.OneToOneField( + on_delete=models.CASCADE, to='gestion.Profile', null=True, related_name='cof' @@ -89,6 +90,7 @@ class Migration(migrations.Migration): model_name='cofprofile', name='profile', field=models.OneToOneField( + on_delete=models.CASCADE, to='gestion.Profile', related_name='cof' ), diff --git a/cof/models.py b/cof/models.py index dafe9996..bfbaaf5f 100644 --- a/cof/models.py +++ b/cof/models.py @@ -113,7 +113,11 @@ class Event(models.Model): @python_2_unicode_compatible class EventCommentField(models.Model): - event = models.ForeignKey(Event, related_name="commentfields") + event = models.ForeignKey( + Event, + on_delete=models.CASCADE, + related_name="commentfields" + ) name = models.CharField("Champ", max_length=200) fieldtype = models.CharField("Type", max_length=10, choices=TYPE_COMMENT_FIELD, default="text") @@ -128,9 +132,16 @@ class EventCommentField(models.Model): @python_2_unicode_compatible class EventCommentValue(models.Model): - commentfield = models.ForeignKey(EventCommentField, related_name="values") - registration = models.ForeignKey("EventRegistration", - related_name="comments") + commentfield = models.ForeignKey( + EventCommentField, + on_delete=models.CASCADE, + related_name="values" + ) + registration = models.ForeignKey( + "EventRegistration", + on_delete=models.CASCADE, + related_name="comments" + ) content = models.TextField("Contenu", blank=True, null=True) def __str__(self): @@ -139,7 +150,11 @@ class EventCommentValue(models.Model): @python_2_unicode_compatible class EventOption(models.Model): - event = models.ForeignKey(Event, related_name="options") + event = models.ForeignKey( + Event, + on_delete=models.CASCADE, + related_name="options" + ) name = models.CharField("Option", max_length=200) multi_choices = models.BooleanField("Choix multiples", default=False) @@ -152,7 +167,11 @@ class EventOption(models.Model): @python_2_unicode_compatible class EventOptionChoice(models.Model): - event_option = models.ForeignKey(EventOption, related_name="choices") + event_option = models.ForeignKey( + EventOption, + on_delete=models.CASCADE, + related_name="choices" + ) value = models.CharField("Valeur", max_length=200) class Meta: @@ -165,8 +184,14 @@ class EventOptionChoice(models.Model): @python_2_unicode_compatible class EventRegistration(models.Model): - user = models.ForeignKey(User) - event = models.ForeignKey(Event) + user = models.ForeignKey( + User, + on_delete=models.CASCADE + ) + event = models.ForeignKey( + Event, + on_delete=models.CASCADE + ) options = models.ManyToManyField(EventOptionChoice) filledcomments = models.ManyToManyField(EventCommentField, through=EventCommentValue) @@ -197,7 +222,11 @@ class Survey(models.Model): @python_2_unicode_compatible class SurveyQuestion(models.Model): - survey = models.ForeignKey(Survey, related_name="questions") + survey = models.ForeignKey( + Survey, + on_delete=models.CASCADE, + related_name="questions" + ) question = models.CharField("Question", max_length=200) multi_answers = models.BooleanField("Choix multiples", default=False) @@ -210,7 +239,11 @@ class SurveyQuestion(models.Model): @python_2_unicode_compatible class SurveyQuestionAnswer(models.Model): - survey_question = models.ForeignKey(SurveyQuestion, related_name="answers") + survey_question = models.ForeignKey( + SurveyQuestion, + on_delete=models.CASCADE, + related_name="answers" + ) answer = models.CharField("Réponse", max_length=200) class Meta: @@ -222,8 +255,14 @@ class SurveyQuestionAnswer(models.Model): @python_2_unicode_compatible class SurveyAnswer(models.Model): - user = models.ForeignKey(User) - survey = models.ForeignKey(Survey) + user = models.ForeignKey( + User, + on_delete=models.CASCADE + ) + survey = models.ForeignKey( + Survey, + on_delete=models.CASCADE + ) answers = models.ManyToManyField(SurveyQuestionAnswer, related_name="selected_by") @@ -240,7 +279,10 @@ class SurveyAnswer(models.Model): @python_2_unicode_compatible class CalendarSubscription(models.Model): token = models.UUIDField() - user = models.OneToOneField(User) + user = models.OneToOneField( + User, + on_delete=models.CASCADE + ) other_shows = models.ManyToManyField(Spectacle) subscribe_to_events = models.BooleanField(default=True) subscribe_to_my_shows = models.BooleanField(default=True) diff --git a/cof/petits_cours_models.py b/cof/petits_cours_models.py index 753e8674..e67a20bf 100644 --- a/cof/petits_cours_models.py +++ b/cof/petits_cours_models.py @@ -35,8 +35,15 @@ class PetitCoursSubject(models.Model): class PetitCoursAbility(models.Model): - user = models.ForeignKey(User) - matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière")) + user = models.ForeignKey( + User, + on_delete=models.CASCADE + ) + matiere = models.ForeignKey( + PetitCoursSubject, + on_delete=models.CASCADE, + verbose_name=_("Matière") + ) niveau = models.CharField(_("Niveau"), choices=LEVELS_CHOICES, max_length=choices_length(LEVELS_CHOICES)) @@ -84,7 +91,11 @@ class PetitCoursDemande(models.Model): remarques = models.TextField(_("Remarques et précisions"), blank=True) traitee = models.BooleanField(_("Traitée"), default=False) - traitee_par = models.ForeignKey(User, blank=True, null=True) + traitee_par = models.ForeignKey( + User, + on_delete=models.CASCADE, + blank=True, null=True + ) processed = models.DateTimeField(_("Date de traitement"), blank=True, null=True) created = models.DateTimeField(_("Date de création"), auto_now_add=True) @@ -126,9 +137,20 @@ class PetitCoursDemande(models.Model): class PetitCoursAttribution(models.Model): - user = models.ForeignKey(User) - demande = models.ForeignKey(PetitCoursDemande, verbose_name=_("Demande")) - matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matière")) + user = models.ForeignKey( + User, + on_delete=models.CASCADE + ) + demande = models.ForeignKey( + PetitCoursDemande, + on_delete=models.CASCADE, + verbose_name=_("Demande") + ) + matiere = models.ForeignKey( + PetitCoursSubject, + on_delete=models.CASCADE, + verbose_name=_("Matière") + ) date = models.DateTimeField(_("Date d'attribution"), auto_now_add=True) rank = models.IntegerField("Rang dans l'email") selected = models.BooleanField(_("Sélectionné par le demandeur"), @@ -145,8 +167,15 @@ class PetitCoursAttribution(models.Model): class PetitCoursAttributionCounter(models.Model): - user = models.ForeignKey(User) - matiere = models.ForeignKey(PetitCoursSubject, verbose_name=_("Matiere")) + user = models.ForeignKey( + User, + on_delete=models.CASCADE + ) + matiere = models.ForeignKey( + PetitCoursSubject, + on_delete=models.CASCADE, + verbose_name=_("Matiere") + ) count = models.IntegerField("Nombre d'envois", default=0) @classmethod diff --git a/gestion/migrations/0001_initial.py b/gestion/migrations/0001_initial.py index daeaa39b..a301bb9a 100644 --- a/gestion/migrations/0001_initial.py +++ b/gestion/migrations/0001_initial.py @@ -21,7 +21,10 @@ class Migration(migrations.Migration): ('occupation', models.CharField(choices=[('exterieur', 'Extérieur'), ('1A', '1A'), ('2A', '2A'), ('3A', '3A'), ('4A', '4A'), ('archicube', 'Archicube'), ('doctorant', 'Doctorant'), ('CST', 'CST')], verbose_name='Occupation', max_length=9, default='1A')), ('departement', models.CharField(verbose_name='Département', max_length=50, blank=True)), ('comments', models.TextField(verbose_name="Commentaires visibles par l'utilisateur", blank=True)), - ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, related_name='profile')), + ('user', models.OneToOneField( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL, + related_name='profile')), ], options={ 'verbose_name': 'Profil', diff --git a/gestion/models.py b/gestion/models.py index 81335ddc..78d8aaab 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -17,9 +17,13 @@ OCCUPATION_CHOICES = ( ('CST', _("CST")), ) -class Profile(models.Model): - user = models.OneToOneField(User, related_name="profile") +class Profile(models.Model): + user = models.OneToOneField( + User, + on_delete=models.CASCADE, + related_name="profile" + ) login_clipper = models.CharField("Login clipper", max_length=8, blank=True) phone = models.CharField("Téléphone", max_length=20, blank=True) occupation = models.CharField(_("Occupation"), @@ -39,6 +43,7 @@ class Profile(models.Model): def __str__(self): return self.user.username + @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: diff --git a/kfet/migrations/0048_generic_profiles.py b/kfet/migrations/0048_generic_profiles.py index e3fda98b..ef5eae4e 100644 --- a/kfet/migrations/0048_generic_profiles.py +++ b/kfet/migrations/0048_generic_profiles.py @@ -15,6 +15,9 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='account', name='cofprofile', - field=models.OneToOneField(to='gestion.Profile', related_name='account_kfet'), + field=models.OneToOneField( + to='gestion.Profile', + on_delete=models.CASCADE, + related_name='account_kfet'), ), ] From 1aed36330f462727ea6e656beddb20d03ec19460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 00:31:08 +0100 Subject: [PATCH 07/18] Write modern-style urls - Proper use of include - Defining namespaces (I do not use them for now because many urls are going to change) - Do not try to reverse with old-style references: 'cof.views.XXX' --- bda/templates/bda/resume_places.html | 2 +- cof/templates/cof/base_header.html | 2 +- cof/templates/cof/calendar_subscription.html | 2 +- cof/templates/cof/event.html | 2 +- cof/templates/cof/survey.html | 2 +- cof/templates/cof/utile_cof.html | 10 ++-- cof/templates/event_status.html | 2 +- cof/templates/home.html | 18 ++++---- cof/templates/registration.html | 2 +- .../registration/password_change_done.html | 2 +- .../registration/password_change_form.html | 2 +- cof/templates/registration_form.html | 2 +- cof/templates/survey_status.html | 2 +- cof/templates/utile_bda.html | 4 +- cof/urls.py | 39 ++++++++++++---- gestioCOF/urls.py | 46 +++++++++++++------ gestion/urls.py | 5 +- gestion/views.py | 2 +- 18 files changed, 92 insertions(+), 54 deletions(-) diff --git a/bda/templates/bda/resume_places.html b/bda/templates/bda/resume_places.html index 226e697a..7cbd06ea 100644 --- a/bda/templates/bda/resume_places.html +++ b/bda/templates/bda/resume_places.html @@ -16,7 +16,7 @@

Total à payer : {{ total|floatformat }}€


Ne manque pas un spectacle avec le - calendrier + calendrier automatique !

{% else %}

Vous n'avez aucune place :(

diff --git a/cof/templates/cof/base_header.html b/cof/templates/cof/base_header.html index 4713a286..dd9c1967 100644 --- a/cof/templates/cof/base_header.html +++ b/cof/templates/cof/base_header.html @@ -3,7 +3,7 @@ {% block content %}
@@ -105,8 +105,8 @@

Liens utiles

diff --git a/cof/templates/registration.html b/cof/templates/registration.html index 559226b7..e81d7b2b 100644 --- a/cof/templates/registration.html +++ b/cof/templates/registration.html @@ -16,7 +16,7 @@ // On attend que la page soit prête pour executer le code $(document).ready(function() { $('input#search_autocomplete').yourlabsAutocomplete({ - url: '{% url 'cof.autocomplete.autocomplete' %}', + url: '{% url 'autocomplete' %}', minimumCharacters: 3, id: 'search_autocomplete', choiceSelector: 'li:has(a)', diff --git a/cof/templates/registration/password_change_done.html b/cof/templates/registration/password_change_done.html index 2f2e4eea..9f2c4a60 100644 --- a/cof/templates/registration/password_change_done.html +++ b/cof/templates/registration/password_change_done.html @@ -5,5 +5,5 @@ {% block realcontent %}

Mot de passe modifié avec succès !

-

Retour au menu principal

+

Retour au menu principal

{% endblock %} diff --git a/cof/templates/registration/password_change_form.html b/cof/templates/registration/password_change_form.html index f579fb31..d9a3f66a 100644 --- a/cof/templates/registration/password_change_form.html +++ b/cof/templates/registration/password_change_form.html @@ -5,7 +5,7 @@ {% block realcontent %}

Changement de mot de passe

- + {% csrf_token %} {{ form | bootstrap }} diff --git a/cof/templates/registration_form.html b/cof/templates/registration_form.html index 97bc375c..2f9bb340 100644 --- a/cof/templates/registration_form.html +++ b/cof/templates/registration_form.html @@ -7,7 +7,7 @@ {% else %}

Inscription d'un nouveau compte (extérieur ?)

{% endif %} - + {% csrf_token %} {{ user_form | bootstrap }} diff --git a/cof/templates/survey_status.html b/cof/templates/survey_status.html index 2e8b28fd..820aeb38 100644 --- a/cof/templates/survey_status.html +++ b/cof/templates/survey_status.html @@ -11,7 +11,7 @@ {% endif %}

Filtres

{% include "tristate_js.html" %} - + {% csrf_token %} {{ form.as_p }} diff --git a/cof/templates/utile_bda.html b/cof/templates/utile_bda.html index 83b96fb8..854009c1 100644 --- a/cof/templates/utile_bda.html +++ b/cof/templates/utile_bda.html @@ -7,7 +7,7 @@

Liens utiles du BdA

Listes mail

{% endblock %} diff --git a/cof/urls.py b/cof/urls.py index ca310382..cc9df782 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -7,12 +7,20 @@ from . import views, petits_cours_views export_patterns = [ - url(r'^members$', views.export_members), + url(r'^members$', + views.export_members, + name="export.members"), url(r'^mega/avecremarques$', views.export_mega_remarksonly), - url(r'^mega/participants$', views.export_mega_participants), - url(r'^mega/orgas$', views.export_mega_orgas), + url(r'^mega/participants$', + views.export_mega_participants, + name="export.mega.participants"), + url(r'^mega/orgas$', + views.export_mega_orgas, + name="export.mega.orgas"), url(r'^mega/(?P.+)$', views.export_mega_bytype), - url(r'^mega$', views.export_mega), + url(r'^mega$', + views.export_mega, + name="export.mega"), ] petitcours_patterns = [ @@ -37,19 +45,30 @@ petitcours_patterns = [ ] surveys_patterns = [ - url(r'^(?P\d+)/status$', views.survey_status), - url(r'^(?P\d+)$', views.survey), + url(r'^(?P\d+)/status$', + views.survey_status, + name="survey.status"), + url(r'^(?P\d+)$', + views.survey, + name="survey"), ] events_patterns = [ - url(r'^(?P\d+)$', views.event), - url(r'^(?P\d+)/status$', views.event_status), + url(r'^(?P\d+)$', + views.event, + name="event"), + url(r'^(?P\d+)/status$', + views.event_status, + name="event.status"), ] calendar_patterns = [ - url(r'^subscription$', 'cof.views.calendar'), + url(r'^subscription$', + views.calendar, + name="calendar"), url(r'^(?P[a-z0-9-]+)/calendar.ics$', - 'cof.views.calendar_ics') + views.calendar_ics, + name="calendar.ics") ] clubs_patterns = [ diff --git a/gestioCOF/urls.py b/gestioCOF/urls.py index ec531778..1c9b5cd3 100644 --- a/gestioCOF/urls.py +++ b/gestioCOF/urls.py @@ -5,6 +5,9 @@ Fichier principal de configuration des urls du projet GestioCOF """ import autocomplete_light +import gestion.urls +import kfet.urls +import bda.urls from django.conf import settings from django.conf.urls import include, url @@ -21,19 +24,20 @@ from cof.autocomplete import autocomplete from gestion import views as gestion_views autocomplete_light.autodiscover() + admin.autodiscover() urlpatterns = [ # Page d'accueil url(r'^$', cof_views.home, name='home'), # The common views - url(r"^", include("gestion.urls", namespace='gestion')), + url(r"^", include(gestion.urls, namespace="gestion")), # Admin urls url(r'^admin/logout/', gestion_views.logout), url(r'^admin/doc/', include('django.contrib.admindocs.urls')), - url(r'^admin/', include(admin.site.urls)), + url(r'^admin/', admin.site.urls), # Le BdA - url(r'^bda/', include('bda.urls')), + url(r'^bda/', include(bda.urls)), # Les exports url(r'^export/', include(export_patterns)), # Les petits cours @@ -47,12 +51,16 @@ urlpatterns = [ # Clubs url(r'^clubs/', include(clubs_patterns)), # Infos persos - url(r'^outsider/password-change$', django_views.password_change), + url(r'^outsider/password-change$', + django_views.password_change, + name="password_change"), url(r'^outsider/password-change-done$', django_views.password_change_done, name='password_change_done'), # Inscription d'un nouveau membre - url(r'^registration$', cof_views.registration), + url(r'^registration$', + cof_views.registration, + name="registration"), url(r'^registration/clipper/(?P[\w-]+)$', cof_views.registration_form2, name="clipper-registration"), url(r'^registration/user/(?P.+)$', @@ -60,21 +68,33 @@ urlpatterns = [ url(r'^registration/empty$', cof_views.registration_form2, name="empty-registration"), # Autocompletion - url(r'^autocomplete/registration$', autocomplete), + url(r'^autocomplete/registration$', + autocomplete, + name="autocomplete"), url(r'^autocomplete/', include('autocomplete_light.urls')), # Liens utiles du COF et du BdA - url(r'^utile_cof$', cof_views.utile_cof), - url(r'^utile_bda$', cof_views.utile_bda), - url(r'^utile_bda/bda_diff$', cof_views.liste_bdadiff), - url(r'^utile_cof/diff_cof$', cof_views.liste_diffcof), - url(r'^utile_bda/bda_revente$', cof_views.liste_bdarevente), - url(r'^k-fet/', include('kfet.urls')), + url(r'^utile_cof$', + cof_views.utile_cof, + name="utile_cof"), + url(r'^utile_bda$', + cof_views.utile_bda, + name="utile_bda"), + url(r'^utile_bda/bda_diff$', + cof_views.liste_bdadiff, + name="liste_bda_diff"), + url(r'^utile_cof/diff_cof$', + cof_views.liste_diffcof, + name="liste_diffcof"), + url(r'^utile_bda/bda_revente$', + cof_views.liste_bdarevente, + name="liste_bdarevente"), + url(r'^k-fet/', include(kfet.urls)), ] if 'debug_toolbar' in settings.INSTALLED_APPS: import debug_toolbar urlpatterns += [ - url(r'^__debug__/', include(debug_toolbar.urls)), + url(r'^__debug__/', debug_toolbar.urls), ] # Si on est en production, MEDIA_ROOT est servi par Apache. diff --git a/gestion/urls.py b/gestion/urls.py index 55e5658a..c1cb3db6 100644 --- a/gestion/urls.py +++ b/gestion/urls.py @@ -1,12 +1,11 @@ -from django.conf.urls import url, include +from django.conf.urls import url from django.views.generic.base import TemplateView from django.contrib.auth import views as django_views -from django.contrib import admin from django_cas_ng import views as django_cas_views from . import views - +app_name = "gestion" urlpatterns = [ # Profile edition url(r"^profile/?$", views.profile, name="profile"), diff --git a/gestion/views.py b/gestion/views.py index 7b3a4997..0a210918 100644 --- a/gestion/views.py +++ b/gestion/views.py @@ -16,7 +16,7 @@ from .forms import ProfileForm, UserForm def login(request): if request.user.is_authenticated(): - return redirect("cof.views.home") + return redirect("home") context = {} # Fetch the next page from the request data if request.method == "GET" and 'next' in request.GET: From 2dcc17298add141f1e3ed1e55fe99590a4859dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 19:27:23 +0100 Subject: [PATCH 08/18] Use Django 1.11 (beta 1) Starting to use Django 1.11. The final version will be released before we push this to production. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 06f6c46e..0e6dc704 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ configparser==3.5.0 -Django==1.8.* +Django==1.11b1 django-autocomplete-light==2.3.3 django-autoslug==1.9.3 django-cas-ng==3.5.5 From 68c0ff559dfe82966cbeb633f8895cdb9f03aa15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 20:01:11 +0100 Subject: [PATCH 09/18] Drop Grappelli It's ugly and does not really improve the admin site --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 0e6dc704..b6debf1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ Django==1.11b1 django-autocomplete-light==2.3.3 django-autoslug==1.9.3 django-cas-ng==3.5.5 -django-grappelli==2.8.1 django-recaptcha==1.0.5 mysqlclient==1.3.7 Pillow==3.3.0 From e1bab7e4edb3b768c99990eb1fde0e7bb25cd9d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 20:00:32 +0100 Subject: [PATCH 10/18] Use the AppConfig class --- bda/apps.py | 6 ++++++ bds/apps.py | 6 ++++++ cof/apps.py | 6 ++++++ gestioCOF/settings_dev.py | 10 +++++----- gestion/apps.py | 6 ++++++ kfet/apps.py | 7 +------ 6 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 bda/apps.py create mode 100644 bds/apps.py create mode 100644 cof/apps.py create mode 100644 gestion/apps.py diff --git a/bda/apps.py b/bda/apps.py new file mode 100644 index 00000000..583936c7 --- /dev/null +++ b/bda/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BdAConfig(AppConfig): + name = "bda" + verbose_name = "Gestion des tirages du BdA" diff --git a/bds/apps.py b/bds/apps.py new file mode 100644 index 00000000..7c08d34e --- /dev/null +++ b/bds/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BDSConfig(AppConfig): + name = "bds" + verbose_name = "Application de gestion du BDS" diff --git a/cof/apps.py b/cof/apps.py new file mode 100644 index 00000000..f981ee91 --- /dev/null +++ b/cof/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class COFConfig(AppConfig): + name = "cof" + verbose_name = "Application de gestion du COF" diff --git a/gestioCOF/settings_dev.py b/gestioCOF/settings_dev.py index 253f924f..feacba52 100644 --- a/gestioCOF/settings_dev.py +++ b/gestioCOF/settings_dev.py @@ -42,12 +42,12 @@ INSTALLED_APPS = ( 'bootstrapform', 'channels', 'widget_tweaks', - 'bda', - 'bds', - 'cof', - 'gestion', - 'kfet', 'custommail', + 'bda.apps.BdAConfig', + 'bds.apps.BDSConfig', + 'cof.apps.COFConfig', + 'gestion.apps.GestionConfig', + 'kfet.apps.KFetConfig', ) MIDDLEWARE_CLASSES = ( diff --git a/gestion/apps.py b/gestion/apps.py new file mode 100644 index 00000000..efb14b29 --- /dev/null +++ b/gestion/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class GestionConfig(AppConfig): + name = "gestion" + verbose_name = "Gestion des outils communs COF/BDS" diff --git a/kfet/apps.py b/kfet/apps.py index 29f9f98e..ae83817b 100644 --- a/kfet/apps.py +++ b/kfet/apps.py @@ -1,11 +1,6 @@ -# -*- coding: utf-8 -*- - -from __future__ import (absolute_import, division, - print_function, unicode_literals) -from builtins import * - from django.apps import AppConfig + class KFetConfig(AppConfig): name = 'kfet' verbose_name = "Application K-Fêt" From 8b905f66dc605b99bbbf1de068b393cc81fed562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Wed, 22 Feb 2017 19:26:37 +0100 Subject: [PATCH 11/18] Remove dependencies of an old version of dal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Django-autocomplete-light does not support the `modelform_factory` anymore in recent versions. We are actually using an old version of dal because of this. This had to be dropped at some point… So now is a good time --- bda/admin.py | 3 --- bda/autocomplete_light_registry.py | 18 ------------------ cof/admin.py | 3 --- cof/autocomplete_light_registry.py | 10 ---------- cof/urls.py | 5 ++--- gestioCOF/urls.py | 3 --- 6 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 bda/autocomplete_light_registry.py delete mode 100644 cof/autocomplete_light_registry.py diff --git a/bda/admin.py b/bda/admin.py index fc10c326..26f6042f 100644 --- a/bda/admin.py +++ b/bda/admin.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import autocomplete_light from datetime import timedelta from custommail.shortcuts import send_mass_custom_mail @@ -119,8 +118,6 @@ class AttributionAdmin(admin.ModelAdmin): class ChoixSpectacleAdmin(admin.ModelAdmin): - form = autocomplete_light.modelform_factory(ChoixSpectacle, exclude=[]) - def tirage(self, obj): return obj.participant.tirage list_display = ("participant", "tirage", "spectacle", "priority", diff --git a/bda/autocomplete_light_registry.py b/bda/autocomplete_light_registry.py deleted file mode 100644 index 6c2f3ea6..00000000 --- a/bda/autocomplete_light_registry.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import division -from __future__ import print_function -from __future__ import unicode_literals - -import autocomplete_light - -from bda.models import Participant, Spectacle - -autocomplete_light.register( - Participant, search_fields=('user__username', 'user__first_name', - 'user__last_name'), - autocomplete_js_attributes={'placeholder': 'participant...'}) - -autocomplete_light.register( - Spectacle, search_fields=('title', ), - autocomplete_js_attributes={'placeholder': 'spectacle...'}) diff --git a/cof/admin.py b/cof/admin.py index 177a5adf..ce998cd4 100644 --- a/cof/admin.py +++ b/cof/admin.py @@ -6,8 +6,6 @@ from django.core.urlresolvers import reverse from django.utils.safestring import mark_safe import django.utils.six as six -import autocomplete_light - from .petits_cours_models import PetitCoursDemande, \ PetitCoursSubject, PetitCoursAbility, PetitCoursAttribution, \ PetitCoursAttributionCounter @@ -95,7 +93,6 @@ class EventAdmin(admin.ModelAdmin): class EventRegistrationAdmin(admin.ModelAdmin): - form = autocomplete_light.modelform_factory(EventRegistration, exclude=[]) list_display = ('__unicode__' if six.PY2 else '__str__', 'event', 'user', 'paid') list_filter = ('paid',) diff --git a/cof/autocomplete_light_registry.py b/cof/autocomplete_light_registry.py deleted file mode 100644 index 4c62d995..00000000 --- a/cof/autocomplete_light_registry.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- - -import autocomplete_light - -from django.contrib.auth.models import User - -autocomplete_light.register( - User, search_fields=('username', 'first_name', 'last_name'), - attrs={'placeholder': 'membre...'} -) diff --git a/cof/urls.py b/cof/urls.py index ca310382..52826f29 100644 --- a/cof/urls.py +++ b/cof/urls.py @@ -47,9 +47,8 @@ events_patterns = [ ] calendar_patterns = [ - url(r'^subscription$', 'cof.views.calendar'), - url(r'^(?P[a-z0-9-]+)/calendar.ics$', - 'cof.views.calendar_ics') + url(r'^subscription$', views.calendar), + url(r'^(?P[a-z0-9-]+)/calendar.ics$', views.calendar_ics) ] clubs_patterns = [ diff --git a/gestioCOF/urls.py b/gestioCOF/urls.py index ec531778..1df71648 100644 --- a/gestioCOF/urls.py +++ b/gestioCOF/urls.py @@ -4,8 +4,6 @@ Fichier principal de configuration des urls du projet GestioCOF """ -import autocomplete_light - from django.conf import settings from django.conf.urls import include, url from django.conf.urls.static import static @@ -20,7 +18,6 @@ from cof.autocomplete import autocomplete from gestion import views as gestion_views -autocomplete_light.autodiscover() admin.autodiscover() urlpatterns = [ From 69f748acbd1e7b1f2947494f3d86bc1b7f7ba8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 00:43:23 +0100 Subject: [PATCH 12/18] Django1.11-style MiddleWares The design of middlewares has changed in Django 1.11 --- gestioCOF/settings_dev.py | 6 +++--- kfet/middleware.py | 17 ++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/gestioCOF/settings_dev.py b/gestioCOF/settings_dev.py index feacba52..3f5ac2d2 100644 --- a/gestioCOF/settings_dev.py +++ b/gestioCOF/settings_dev.py @@ -50,18 +50,18 @@ INSTALLED_APPS = ( 'kfet.apps.KFetConfig', ) -MIDDLEWARE_CLASSES = ( +MIDDLEWARE = [ 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', - 'kfet.middleware.KFetAuthenticationMiddleware', + 'kfet.middleware.kfet_auth_middleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', -) +] ROOT_URLCONF = 'gestioCOF.urls' diff --git a/kfet/middleware.py b/kfet/middleware.py index dbb192c6..02d3d2f4 100644 --- a/kfet/middleware.py +++ b/kfet/middleware.py @@ -1,17 +1,16 @@ # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, - print_function, unicode_literals) -from builtins import * - -from django.http import HttpResponseForbidden from kfet.backends import KFetBackend -from kfet.models import Account -class KFetAuthenticationMiddleware(object): - def process_request(self, request): - kfet_backend = KFetBackend() + +def kfet_auth_middleware(get_response): + kfet_backend = KFetBackend() + + def middleware(request): temp_request_user = kfet_backend.authenticate(request) if temp_request_user: request.real_user = request.user request.user = temp_request_user + return get_response(request) + + return middleware From 6bf16441e6160557dbc9ab52b82402517a0ea4ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 00:52:31 +0100 Subject: [PATCH 13/18] Drop old context processors Some context processors disappear in Django 1.11, we have to drop them --- gestioCOF/settings_dev.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/gestioCOF/settings_dev.py b/gestioCOF/settings_dev.py index 3f5ac2d2..43e7f5b0 100644 --- a/gestioCOF/settings_dev.py +++ b/gestioCOF/settings_dev.py @@ -76,9 +76,6 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', - 'django.core.context_processors.i18n', - 'django.core.context_processors.media', - 'django.core.context_processors.static', 'gestion.context_processors.context_processor', 'kfet.context_processors.auth', ], From 3f52af8ca01ee1744a0168c23b0ec16352010f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 01:24:28 +0100 Subject: [PATCH 14/18] Upgrade requirements - Upgrade some dependencies - We do not specify the version for some packages: we use them in a very simple way so we may not be affected by upgrades. --- requirements.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/requirements.txt b/requirements.txt index b6debf1c..8da5f3ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,17 +2,17 @@ configparser==3.5.0 Django==1.11b1 django-autocomplete-light==2.3.3 django-autoslug==1.9.3 -django-cas-ng==3.5.5 -django-recaptcha==1.0.5 -mysqlclient==1.3.7 -Pillow==3.3.0 -six==1.10.0 -unicodecsv==0.14.1 -icalendar==3.10 +django-cas-ng==3.5.6 +django-recaptcha==1.2.1 +mysqlclient==1.3.10 +Pillow +six +unicodecsv +icalendar django-bootstrap-form==3.2.1 -asgiref==0.14.0 -daphne==0.14.3 -asgi-redis==0.14.0 +asgiref==1.0.0 +daphne==1.0.3 +asgi-redis==1.0.0 statistics==1.0.3.5 future==0.15.2 django-widget-tweaks==1.4.1 From 7d1c1fc868ac5ffdb283023b73b4b81ca32d0e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 10:47:48 +0100 Subject: [PATCH 15/18] Specify the on_delete strategy - Remove an absurd debug line in the migration - Specify the on_delete strategy for the club-related models --- gestion/migrations/0002_club_support.py | 9 ++++++--- gestion/models.py | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/gestion/migrations/0002_club_support.py b/gestion/migrations/0002_club_support.py index 6b23882b..dc16f400 100644 --- a/gestion/migrations/0002_club_support.py +++ b/gestion/migrations/0002_club_support.py @@ -64,7 +64,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(lambda: 1/0), migrations.CreateModel( name='Club', fields=[ @@ -82,8 +81,12 @@ class Migration(migrations.Migration): ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), ('is_respo', models.BooleanField(verbose_name='Est responsable du club')), ('has_paid', models.BooleanField(verbose_name='A payé sa cotisation')), - ('club', models.ForeignKey(to='gestion.Club')), - ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), + ('club', models.ForeignKey( + to='gestion.Club', + on_delete=models.CASCADE)), + ('user', models.ForeignKey( + on_delete=models.CASCADE, + to=settings.AUTH_USER_MODEL)), ], ), migrations.AddField( diff --git a/gestion/models.py b/gestion/models.py index 98c06d0e..5716cb1b 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -96,7 +96,7 @@ class Club(models.Model): class ClubUser(models.Model): - user = models.ForeignKey(User) - club = models.ForeignKey(Club) + user = models.ForeignKey(User, on_delete=models.CASCADE) + club = models.ForeignKey(Club, on_delete=models.CASCADE) is_respo = models.BooleanField(_("Est responsable du club")) has_paid = models.BooleanField(_("A payé sa cotisation")) From 213c11721e4ded716b01560c693e3849ebde4999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 11:03:28 +0100 Subject: [PATCH 16/18] Prevent petits cours demandes deletion --- cof/migrations/0001_initial.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cof/migrations/0001_initial.py b/cof/migrations/0001_initial.py index fdfeaed4..1ba71322 100644 --- a/cof/migrations/0001_initial.py +++ b/cof/migrations/0001_initial.py @@ -310,7 +310,7 @@ class Migration(migrations.Migration): model_name='petitcoursdemande', name='traitee_par', field=models.ForeignKey( - on_delete=models.CASCADE, + on_delete=models.PROTECT, blank=True, to=settings.AUTH_USER_MODEL, null=True), @@ -319,7 +319,7 @@ class Migration(migrations.Migration): model_name='petitcoursattributioncounter', name='matiere', field=models.ForeignKey( - on_delete=models.CASCADE, + on_delete=models.PROTECT, verbose_name='Matiere', to='cof.PetitCoursSubject'), ), @@ -327,7 +327,7 @@ class Migration(migrations.Migration): model_name='petitcoursattributioncounter', name='user', field=models.ForeignKey( - on_delete=models.CASCADE, + on_delete=models.PROTECT, to=settings.AUTH_USER_MODEL), ), migrations.AddField( @@ -342,7 +342,7 @@ class Migration(migrations.Migration): model_name='petitcoursattribution', name='matiere', field=models.ForeignKey( - on_delete=models.CASCADE, + on_delete=models.PROTECT, verbose_name='Mati\xe8re', to='cof.PetitCoursSubject'), ), From 7742ad999f165d7e75b3dadbc01baf67c7ffc5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 11:05:53 +0100 Subject: [PATCH 17/18] Typo in url reverse name `liste_bda_diff` -> `liste_bdadiff` --- gestioCOF/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gestioCOF/urls.py b/gestioCOF/urls.py index 1c9b5cd3..e95bb924 100644 --- a/gestioCOF/urls.py +++ b/gestioCOF/urls.py @@ -81,7 +81,7 @@ urlpatterns = [ name="utile_bda"), url(r'^utile_bda/bda_diff$', cof_views.liste_bdadiff, - name="liste_bda_diff"), + name="liste_bdadiff"), url(r'^utile_cof/diff_cof$', cof_views.liste_diffcof, name="liste_diffcof"), From 83e73376ad141fa9ded7ef163b38ce790b1b3a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Thu, 23 Feb 2017 12:04:33 +0100 Subject: [PATCH 18/18] Change CofProfile to Profile in kfet/backends.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - K-Fêt accounts are now linked to profiles - There is no need to perform the `get_or_create` as long as the profile creation has been automated. - This file is now PEP8 compliant --- kfet/backends.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/kfet/backends.py b/kfet/backends.py index d0dcc5f6..56d85b81 100644 --- a/kfet/backends.py +++ b/kfet/backends.py @@ -1,15 +1,11 @@ # -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, - print_function, unicode_literals) -from builtins import * - import hashlib from django.contrib.auth.models import User, Permission -from cof.models import CofProfile from kfet.models import Account, GenericTeamToken + class KFetBackend(object): def authenticate(self, request): password = request.POST.get('KFETPASSWORD', '') @@ -17,8 +13,8 @@ class KFetBackend(object): if not password: return None + password_sha256 = hashlib.sha256(password.encode('utf-8')).hexdigest() try: - password_sha256 = hashlib.sha256(password.encode('utf-8')).hexdigest() account = Account.objects.get(password=password_sha256) user = account.profile.user except Account.DoesNotExist: @@ -26,16 +22,20 @@ class KFetBackend(object): return user + class GenericTeamBackend(object): + """ + Authenticate using the generic_team user. + """ def authenticate(self, username=None, token=None): valid_token = GenericTeamToken.objects.get(token=token) if username == 'kfet_genericteam' and valid_token: # Création du user s'il n'existe pas déjà user, _ = User.objects.get_or_create(username='kfet_genericteam') - profile, _ = CofProfile.objects.get_or_create(user=user) account, _ = Account.objects.get_or_create( - profile=profile, - trigramme='GNR') + profile=user.profile, + trigramme='GNR' + ) # Ajoute la permission kfet.is_team à ce user perm_is_team = Permission.objects.get(codename='is_team')