diff --git a/bds/apps.py b/bds/apps.py index 7c08d34e..525776ec 100644 --- a/bds/apps.py +++ b/bds/apps.py @@ -1,6 +1,36 @@ from django.apps import AppConfig +from django.db.models.signals import post_migrate + + +def setup_groups(sender, apps, **kwargs): + """ + Add the appropriate permissions to the "member" and "buro" groups after the + `post_migrate` signal since the permissions will only be inserted in the + database at the very end of the migrations. + """ + Group = apps.get_model("auth", "Group") + Permission = apps.get_model("auth", "Permission") + + # Buro members have perms bds.* and gestion.* + buro, _ = Group.objects.get_or_create(name="bds_buro") + app_perms = Permission.objects.filter( + content_type__app_label__in=["cof", "gestion"] + ) + buro.permissions.add(*app_perms) + + # Members have perm bds.member + members, _ = Group.objects.get_or_create(name="bds_members") + perm = Permission.objects.get( + codename="member", + content_type__app_label="bds" + ) + members.permissions.add(perm) class BDSConfig(AppConfig): name = "bds" verbose_name = "Application de gestion du BDS" + + def ready(self): + # https://docs.djangoproject.com/en/1.11/ref/signals/#post-migrate + post_migrate.connect(setup_groups, sender=self) diff --git a/cof/admin.py b/cof/admin.py index fc6fe515..59018f20 100644 --- a/cof/admin.py +++ b/cof/admin.py @@ -9,9 +9,7 @@ from .petits_cours_models import PetitCoursDemande, \ PetitCoursSubject, PetitCoursAbility, PetitCoursAttribution, \ PetitCoursAttributionCounter from .models import ( - SurveyQuestionAnswer, SurveyQuestion, CofProfile, EventOption, - EventOptionChoice, Event, EventCommentField, EventRegistration, - Survey + SurveyQuestionAnswer, SurveyQuestion, CofProfile, Survey ) @@ -62,43 +60,6 @@ class SurveyAdmin(admin.ModelAdmin): ] -class EventOptionChoiceInline(admin.TabularInline): - model = EventOptionChoice - - -@add_link_field(desc_text=lambda x: "Choix", - link_text=lambda x: "Éditer les choix") -class EventOptionInline(admin.TabularInline): - model = EventOption - - -class EventCommentFieldInline(admin.TabularInline): - model = EventCommentField - - -class EventOptionAdmin(admin.ModelAdmin): - search_fields = ('event__title', 'name') - inlines = [ - EventOptionChoiceInline, - ] - - -class EventAdmin(admin.ModelAdmin): - search_fields = ('title', 'location', 'description') - inlines = [ - EventOptionInline, - EventCommentFieldInline, - ] - - -class EventRegistrationAdmin(admin.ModelAdmin): - list_display = ('__unicode__' if six.PY2 else '__str__', 'event', 'user', - 'paid') - list_filter = ('paid',) - search_fields = ('user__username', 'user__first_name', 'user__last_name', - 'user__email', 'event__title') - - class PetitCoursAbilityAdmin(admin.ModelAdmin): list_display = ('user', 'matiere', 'niveau', 'agrege') search_fields = ('user__username', 'user__first_name', 'user__last_name', @@ -133,8 +94,6 @@ class PetitCoursDemandeAdmin(admin.ModelAdmin): 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(PetitCoursSubject) admin.site.register(PetitCoursAbility, PetitCoursAbilityAdmin) @@ -142,4 +101,3 @@ admin.site.register(PetitCoursAttribution, PetitCoursAttributionAdmin) admin.site.register(PetitCoursAttributionCounter, PetitCoursAttributionCounterAdmin) admin.site.register(PetitCoursDemande, PetitCoursDemandeAdmin) -admin.site.register(EventRegistration, EventRegistrationAdmin) diff --git a/cof/apps.py b/cof/apps.py index f981ee91..c40e8896 100644 --- a/cof/apps.py +++ b/cof/apps.py @@ -1,6 +1,36 @@ from django.apps import AppConfig +from django.db.models.signals import post_migrate + + +def setup_groups(sender, apps, **kwargs): + """ + Add the appropriate permissions to the "member" and "buro" groups after the + `post_migrate` signal since the permissions will only be inserted in the + database at the very end of the migrations. + """ + Group = apps.get_model("auth", "Group") + Permission = apps.get_model("auth", "Permission") + + # Buro members have perms cof.* and gestion.* + buro, _ = Group.objects.get_or_create(name="cof_buro") + app_perms = Permission.objects.filter( + content_type__app_label__in=["cof", "gestion"] + ) + buro.permissions.add(*app_perms) + + # Members have perm cof.member + members, _ = Group.objects.get_or_create(name="cof_members") + perm = Permission.objects.get( + codename="member", + content_type__app_label="cof" + ) + members.permissions.add(perm) class COFConfig(AppConfig): name = "cof" verbose_name = "Application de gestion du COF" + + def ready(self): + # https://docs.djangoproject.com/en/1.11/ref/signals/#post-migrate + post_migrate.connect(setup_groups, sender=self) diff --git a/cof/fixtures/gestion.json b/cof/fixtures/gestion.json index 6d1bd76f..c8020cb6 100644 --- a/cof/fixtures/gestion.json +++ b/cof/fixtures/gestion.json @@ -67,63 +67,6 @@ "model": "cof.surveyquestionanswer", "pk": 5 }, -{ - "fields": { - "old": false, - "description": "On va casser du romain.", - "end_date": "2016-09-12T00:00:00Z", - "title": "Bataille de Gergovie", - "image": "", - "location": "Gergovie", - "registration_open": true, - "start_date": "2016-09-09T00:00:00Z" - }, - "model": "cof.event", - "pk": 1 -}, -{ - "fields": { - "default": "", - "event": 1, - "fieldtype": "text", - "name": "Commentaires" - }, - "model": "cof.eventcommentfield", - "pk": 1 -}, -{ - "fields": { - "multi_choices": true, - "event": 1, - "name": "Potion magique" - }, - "model": "cof.eventoption", - "pk": 1 -}, -{ - "fields": { - "event_option": 1, - "value": "Je suis alergique" - }, - "model": "cof.eventoptionchoice", - "pk": 1 -}, -{ - "fields": { - "event_option": 1, - "value": "J'en veux" - }, - "model": "cof.eventoptionchoice", - "pk": 2 -}, -{ - "fields": { - "event_option": 1, - "value": "Je suis tomb\u00e9 dans la marmite quand j'\u00e9tais petit" - }, - "model": "cof.eventoptionchoice", - "pk": 3 -}, { "fields": { "name": "Bagarre" diff --git a/cof/forms.py b/cof/forms.py index 7f3a0614..072d3e70 100644 --- a/cof/forms.py +++ b/cof/forms.py @@ -12,58 +12,15 @@ from django.forms.formsets import BaseFormSet, formset_factory from django.db.models import Max from django.core.validators import MinLengthValidator -from .models import CofProfile, EventCommentValue, CalendarSubscription +from .models import CofProfile, CalendarSubscription from .widgets import TriStateCheckbox -from gestion.models import Profile +from gestion.models import Profile, EventCommentValue from gestion.shared import lock_table, unlock_table from bda.models import Spectacle -class EventForm(forms.Form): - def __init__(self, *args, **kwargs): - event = kwargs.pop("event") - self.event = event - current_choices = kwargs.pop("current_choices", None) - super(EventForm, self).__init__(*args, **kwargs) - choices = {} - if current_choices: - for choice in current_choices.all(): - if choice.event_option.id not in choices: - choices[choice.event_option.id] = [choice.id] - else: - choices[choice.event_option.id].append(choice.id) - all_choices = choices - for option in event.options.all(): - choices = [(choice.id, choice.value) - for choice in option.choices.all()] - if option.multi_choices: - initial = [] if option.id not in all_choices \ - else all_choices[option.id] - field = forms.MultipleChoiceField( - label=option.name, - choices=choices, - widget=CheckboxSelectMultiple, - required=False, - initial=initial) - else: - initial = None if option.id not in all_choices \ - else all_choices[option.id][0] - field = forms.ChoiceField(label=option.name, - choices=choices, - widget=RadioSelect, - required=False, - initial=initial) - field.option_id = option.id - self.fields["option_%d" % option.id] = field - - def choices(self): - for name, value in self.cleaned_data.items(): - if name.startswith('option_'): - yield (self.fields[name].option_id, value) - - class SurveyForm(forms.Form): def __init__(self, *args, **kwargs): survey = kwargs.pop("survey") diff --git a/cof/migrations/0009_generic_profiles.py b/cof/migrations/0009_generic_profiles.py index e24ebd2f..7f19dc47 100644 --- a/cof/migrations/0009_generic_profiles.py +++ b/cof/migrations/0009_generic_profiles.py @@ -23,27 +23,16 @@ def create_profile(apps, schema_editor): def preserve_perms(apps, schema_editor): - # from django.contrib.auth.management import create_permissions + COFProfile = apps.get_model("cof", "CofProfile") - # 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') - - # creates the groups for COF members and + # create the groups for COF members and staff 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] - - for cofp in CofProfile.objects.filter(is_cof=True): + cprofiles = COFProfile.objects.select_related("profile__user") + for cofp in cprofiles.filter(is_cof=True): cofp.profile.user.groups.add(member) - for cofp in CofProfile.objects.filter(is_buro=True): + for cofp in cprofiles.filter(is_buro=True): cofp.profile.user.groups.add(buro) diff --git a/cof/migrations/0010_create_cof_group.py b/cof/migrations/0010_create_cof_group.py deleted file mode 100644 index f2ce104a..00000000 --- a/cof/migrations/0010_create_cof_group.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import unicode_literals - -from django.db import migrations - - -def create_cof_group(apps, schema_editor): - Group = apps.get_model("auth", "Group") - Group.objects.get_or_create(name="cof_members") - - -def create_buro_group(apps, schema_editor): - Group = apps.get_model("auth", "Group") - Group.objects.get_or_create(name="cof_buro") - - -class Migration(migrations.Migration): - - dependencies = [ - ('cof', '0009_generic_profiles'), - ] - - operations = [ - migrations.RunPython(create_cof_group, migrations.RunPython.noop), - migrations.RunPython(create_buro_group, migrations.RunPython.noop), - ] diff --git a/cof/migrations/0011_delete_clipper_and_custommail.py b/cof/migrations/0011_delete_clipper_and_custommail.py index 92ff4d40..1cfae5f5 100644 --- a/cof/migrations/0011_delete_clipper_and_custommail.py +++ b/cof/migrations/0011_delete_clipper_and_custommail.py @@ -7,7 +7,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('cof', '0010_create_cof_group'), + ('cof', '0009_generic_profiles'), ] operations = [ 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..ea960186 --- /dev/null +++ b/cof/migrations/0013_move_events_to_gestion.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.3 on 2017-07-26 18:29 +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_association_and_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/cof/templates/home.html b/cof/templates/home.html index 556f663b..f17a32bf 100644 --- a/cof/templates/home.html +++ b/cof/templates/home.html @@ -9,16 +9,6 @@