From c217b549bda986aa05c85767a4daba8308fc218b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20P=C3=A9pin?= Date: Sat, 18 Mar 2017 20:48:17 +0000 Subject: [PATCH] Move the events stuff to gestion - The models are moved to the `gestion` app - A new field `associations` is added - The location and datetime fields are removed in favour of a new model `EventTimeSlot` - The old events are migrated to the new app and linked to the `cof_buro` association --- cof/migrations/0013_move_events_to_gestion.py | 111 ++++++++++++ cof/models.py | 120 ------------- gestion/migrations/0003_events.py | 159 ++++++++++++++++++ gestion/models.py | 138 +++++++++++++++ 4 files changed, 408 insertions(+), 120 deletions(-) create mode 100644 cof/migrations/0013_move_events_to_gestion.py create mode 100644 gestion/migrations/0003_events.py diff --git a/cof/migrations/0013_move_events_to_gestion.py b/cof/migrations/0013_move_events_to_gestion.py new file mode 100644 index 00000000..e5f871b1 --- /dev/null +++ b/cof/migrations/0013_move_events_to_gestion.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11b1 on 2017-03-18 20:02 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("cof", "0012_remove_club"), + ("gestion", "0003_events"), + ] + + operations = [ + migrations.RemoveField( + model_name='eventcommentfield', + name='event', + ), + migrations.RemoveField( + model_name='eventcommentvalue', + name='commentfield', + ), + migrations.RemoveField( + model_name='eventcommentvalue', + name='registration', + ), + migrations.RemoveField( + model_name='eventoption', + name='event', + ), + migrations.RemoveField( + model_name='eventoptionchoice', + name='event_option', + ), + migrations.AlterUniqueTogether( + name='eventregistration', + unique_together=set([]), + ), + migrations.RemoveField( + model_name='eventregistration', + name='event', + ), + migrations.RemoveField( + model_name='eventregistration', + name='filledcomments', + ), + migrations.RemoveField( + model_name='eventregistration', + name='options', + ), + migrations.RemoveField( + model_name='eventregistration', + name='user', + ), + migrations.AlterField( + model_name='petitcoursattribution', + name='matiere', + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to='cof.PetitCoursSubject', + verbose_name='Matière' + ), + ), + migrations.AlterField( + model_name='petitcoursattributioncounter', + name='matiere', + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to='cof.PetitCoursSubject', + verbose_name='Matiere' + ), + ), + migrations.AlterField( + model_name='petitcoursattributioncounter', + name='user', + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL + ), + ), + migrations.AlterField( + model_name='petitcoursdemande', + name='traitee_par', + field=models.ForeignKey( + blank=True, null=True, + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL + ), + ), + migrations.DeleteModel( + name='Event', + ), + migrations.DeleteModel( + name='EventCommentField', + ), + migrations.DeleteModel( + name='EventCommentValue', + ), + migrations.DeleteModel( + name='EventOption', + ), + migrations.DeleteModel( + name='EventOptionChoice', + ), + migrations.DeleteModel( + name='EventRegistration', + ), + ] diff --git a/cof/models.py b/cof/models.py index 472937fd..bdbd0e1b 100644 --- a/cof/models.py +++ b/cof/models.py @@ -17,11 +17,6 @@ TYPE_COTIZ_CHOICES = ( ('exterieur', _("Extérieur")), ) -TYPE_COMMENT_FIELD = ( - ('text', _("Texte long")), - ('char', _("Texte court")), -) - class CofProfile(models.Model): profile = models.OneToOneField(Profile, @@ -79,121 +74,6 @@ class CofProfile(models.Model): return self.profile.user.username -@python_2_unicode_compatible -class Event(models.Model): - title = models.CharField("Titre", max_length=200) - location = models.CharField("Lieu", max_length=200) - start_date = models.DateTimeField("Date de début", blank=True, null=True) - end_date = models.DateTimeField("Date de fin", blank=True, null=True) - description = models.TextField("Description", blank=True) - image = models.ImageField("Image", blank=True, null=True, - upload_to="imgs/events/") - registration_open = models.BooleanField("Inscriptions ouvertes", - default=True) - old = models.BooleanField("Archiver (événement fini)", default=False) - - class Meta: - verbose_name = "Événement" - - def __str__(self): - return six.text_type(self.title) - - -@python_2_unicode_compatible -class EventCommentField(models.Model): - 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") - default = models.TextField("Valeur par défaut", blank=True) - - class Meta: - verbose_name = "Champ" - - def __str__(self): - return six.text_type(self.name) - - -@python_2_unicode_compatible -class EventCommentValue(models.Model): - 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): - return "Commentaire de %s" % self.commentfield - - -@python_2_unicode_compatible -class EventOption(models.Model): - 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) - - class Meta: - verbose_name = "Option" - - def __str__(self): - return six.text_type(self.name) - - -@python_2_unicode_compatible -class EventOptionChoice(models.Model): - event_option = models.ForeignKey( - EventOption, - on_delete=models.CASCADE, - related_name="choices" - ) - value = models.CharField("Valeur", max_length=200) - - class Meta: - verbose_name = "Choix" - verbose_name_plural = "Choix" - - def __str__(self): - return six.text_type(self.value) - - -@python_2_unicode_compatible -class EventRegistration(models.Model): - 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) - paid = models.BooleanField("A payé", default=False) - - class Meta: - verbose_name = "Inscription" - unique_together = ("user", "event") - - def __str__(self): - return "Inscription de %s à %s" % (six.text_type(self.user), - six.text_type(self.event.title)) - - @python_2_unicode_compatible class Survey(models.Model): title = models.CharField("Titre", max_length=200) diff --git a/gestion/migrations/0003_events.py b/gestion/migrations/0003_events.py new file mode 100644 index 00000000..5de9f17a --- /dev/null +++ b/gestion/migrations/0003_events.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11b1 on 2017-03-18 20:02 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +def import_events(apps, schema_editor): + # Fetching the cof group + cof = apps.get_model("auth", "Group").objects.get(name="cof_buro") + + # First we deal with Events and Timeslots + OldEvent = apps.get_model("cof", "Event") + NewEvent = apps.get_model("gestion", "Event") + TimeSlot = apps.get_model("gestion", "EventTimeSlot") + # TODO: can it be done more efficiently? + for event in OldEvent.objects.all(): + new_event = NewEvent.objects.create( + title=event.title, + description=event.description, + image=event.image, + registration_open=event.registration_open, + old=event.old + ) + new_event.associations.add(cof) + TimeSlot.objects.create( + event=new_event, + location=event.location, + start_date=event.start_date, + end_date=event.end_date + ) + + # Then we migrate the other models + model_names = [ + "EventCommentField", "EventCommentValue", "EventOption", + "EventOptionChoice", "EventRegistration" + ] + models = [ + (apps.get_model("cof", name), apps.get_model("gestion", name)) + for name in model_names + ] + for OldModel, NewModel in models: + NewModel.objects.bulk_create([ + NewModel(**values) + for values in OldModel.objects.values() + ]) + + +def restore_events(apps, schema_editor): + raise NotImplementedError + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('auth', '0008_alter_user_username_max_length'), + ('gestion', '0002_club_support'), + ] + + operations = [ + migrations.CreateModel( + name='Event', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=200, verbose_name='Titre')), + ('description', models.TextField(blank=True, verbose_name='Description')), + ('image', models.ImageField(blank=True, null=True, upload_to='imgs/events/', verbose_name='Image')), + ('registration_open', models.BooleanField(default=True, verbose_name='Inscriptions ouvertes')), + ('old', models.BooleanField(default=False, verbose_name='Archiver (événement fini)')), + ('associations', models.ManyToManyField(related_name='events', to='auth.Group')), + ], + options={ + 'verbose_name': 'Événement', + }, + ), + migrations.CreateModel( + name='EventTimeSlot', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('location', models.CharField(max_length=200, verbose_name='Lieu')), + ('start_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de début')), + ('end_date', models.DateTimeField(blank=True, null=True, verbose_name='Date de fin')), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion.Event')), + ], + ), + migrations.CreateModel( + name='EventCommentField', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, verbose_name='Champ')), + ('fieldtype', models.CharField(choices=[('text', 'Texte long'), ('char', 'Texte court')], default='text', max_length=10, verbose_name='Type')), + ('default', models.TextField(blank=True, verbose_name='Valeur par défaut')), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='commentfields', to='gestion.Event')), + ], + options={ + 'verbose_name': 'Champ', + }, + ), + migrations.CreateModel( + name='EventCommentValue', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(blank=True, null=True, verbose_name='Contenu')), + ('commentfield', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='values', to='gestion.EventCommentField')), + ], + ), + migrations.CreateModel( + name='EventOption', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, verbose_name='Option')), + ('multi_choices', models.BooleanField(default=False, verbose_name='Choix multiples')), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='options', to='gestion.Event')), + ], + options={ + 'verbose_name': 'Option des événements', + 'verbose_name_plural': 'Options des événements' + }, + ), + migrations.CreateModel( + name='EventOptionChoice', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('value', models.CharField(max_length=200, verbose_name='Valeur')), + ('event_option', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='choices', to='gestion.EventOption')), + ], + options={ + 'verbose_name_plural': 'Choix', + 'verbose_name': 'Choix', + }, + ), + migrations.CreateModel( + name='EventRegistration', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('paid', models.BooleanField(default=False, verbose_name='A payé')), + ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion.Event')), + ('filledcomments', models.ManyToManyField(through='gestion.EventCommentValue', to='gestion.EventCommentField')), + ('options', models.ManyToManyField(to='gestion.EventOptionChoice')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Inscription', + }, + ), + migrations.AddField( + model_name='eventcommentvalue', + name='registration', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='gestion.EventRegistration'), + ), + migrations.AlterUniqueTogether( + name='eventregistration', + unique_together=set([('user', 'event')]), + ), + migrations.RunPython(import_events, restore_events), + ] diff --git a/gestion/models.py b/gestion/models.py index bba33dd9..272a18f5 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -6,6 +6,11 @@ from django.utils.translation import ugettext_lazy as _ from cof.petits_cours_models import choices_length + +# --- +# User management +# --- + OCCUPATION_CHOICES = ( ('exterieur', _("Extérieur")), ('1A', _("1A")), @@ -55,6 +60,10 @@ def post_delete_user(sender, instance, *args, **kwargs): instance.user.delete() +# --- +# Clubs +# --- + class Club(models.Model): ANNUAL = "ANN" SEMESTER = "SEM" @@ -103,3 +112,132 @@ class ClubUser(models.Model): club = models.ForeignKey(Club, on_delete=models.CASCADE) is_respo = models.BooleanField(_("Est responsable du club")) has_paid = models.BooleanField(_("A payé sa cotisation")) + + +# --- +# Events +# --- + +class Event(models.Model): + associations = models.ManyToManyField(Group, related_name="events") + title = models.CharField("Titre", max_length=200) + description = models.TextField("Description", blank=True) + image = models.ImageField( + "Image", blank=True, null=True, upload_to="imgs/events/" + ) + registration_open = models.BooleanField( + "Inscriptions ouvertes", default=True + ) + old = models.BooleanField("Archiver (événement fini)", default=False) + + class Meta: + verbose_name = "Événement" + + def __str__(self): + return self.title + + +class EventTimeSlot(models.Model): + event = models.ForeignKey(Event) + location = models.CharField("Lieu", max_length=200) + start_date = models.DateTimeField("Date de début", blank=True, null=True) + end_date = models.DateTimeField("Date de fin", blank=True, null=True) + + +class EventCommentField(models.Model): + TEXT = "text" + CHAR = "char" + + FIELD_TYPE = [ + (TEXT, _("Texte long")), + (CHAR, _("Texte court")), + ] + + 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=FIELD_TYPE, default=TEXT + ) + default = models.TextField("Valeur par défaut", blank=True) + + class Meta: + verbose_name = "Champ" + + def __str__(self): + return self.name + + +class EventCommentValue(models.Model): + 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): + return "Commentaire de {}".format(self.commentfield) + + +class EventOption(models.Model): + 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) + + class Meta: + verbose_name = "Option des événements" + verbose_name_plural = "Options des événements" + + def __str__(self): + return self.name + + +class EventOptionChoice(models.Model): + event_option = models.ForeignKey( + EventOption, + on_delete=models.CASCADE, + related_name="choices" + ) + value = models.CharField("Valeur", max_length=200) + + class Meta: + verbose_name = "Choix" + verbose_name_plural = "Choix" + + def __str__(self): + return self.value + + +class EventRegistration(models.Model): + 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) + paid = models.BooleanField("A payé", default=False) + + class Meta: + verbose_name = "Inscription" + unique_together = ("user", "event") + + def __str__(self): + return "Inscription de {} à {}".format(self.user, self.event.title)