From f39d1545f0b9065784dda5935290db79f5de8feb Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 10 Feb 2017 19:10:45 +0000 Subject: [PATCH] Generic profiles and migrations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creating profiles for BDS, COF and K-Fêt. --- bds/migrations/0001_initial.py | 21 ++++++ bds/models.py | 8 ++- cof/admin.py | 23 ++++--- cof/migrations/0009_generic_profiles.py | 84 ++++++++++++++++++++++++ cof/models.py | 42 ++++-------- gestion/migrations/0001_initial.py | 31 +++++++++ gestion/models.py | 49 +++++++++++++- kfet/migrations/0048_generic_profiles.py | 20 ++++++ kfet/models.py | 15 +++-- 9 files changed, 246 insertions(+), 47 deletions(-) create mode 100644 bds/migrations/0001_initial.py create mode 100644 cof/migrations/0009_generic_profiles.py create mode 100644 gestion/migrations/0001_initial.py create mode 100644 kfet/migrations/0048_generic_profiles.py diff --git a/bds/migrations/0001_initial.py b/bds/migrations/0001_initial.py new file mode 100644 index 00000000..31d0d9a4 --- /dev/null +++ b/bds/migrations/0001_initial.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gestion', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='BdsProfile', + fields=[ + ('profile', models.OneToOneField(serialize=False, to='gestion.Profile', primary_key=True)), + ], + bases=('gestion.profile',), + ), + ] diff --git a/bds/models.py b/bds/models.py index 71a83623..62b2665c 100644 --- a/bds/models.py +++ b/bds/models.py @@ -1,3 +1,9 @@ from django.db import models -# Create your models here. + +from gestion.models import Profile + +class BdsProfile(Profile): + profile = models.OneToOneField(Profile, on_delete=models.CASCADE) + + # mailing = models.BooleanField("Recevoir les mails BDS", default=False) diff --git a/cof/admin.py b/cof/admin.py index 4ef9ef66..c62ae46e 100644 --- a/cof/admin.py +++ b/cof/admin.py @@ -131,7 +131,7 @@ def ProfileInfo(field, short_description, boolean=False): def getter(self): try: return getattr(self.profile, field) - except CofProfile.DoesNotExist: + except Profile.DoesNotExist: return "" getter.short_description = short_description getter.boolean = boolean @@ -139,13 +139,14 @@ def ProfileInfo(field, short_description, boolean=False): User.profile_login_clipper = FkeyLookup("profile__login_clipper", "Login clipper") -User.profile_num = FkeyLookup("profile__num", "Numéro") +User.profile_num = FkeyLookup("profile__cofprofile__num", + "Numéro") User.profile_phone = ProfileInfo("phone", "Téléphone") User.profile_occupation = ProfileInfo("occupation", "Occupation") User.profile_departement = ProfileInfo("departement", "Departement") -User.profile_mailing_cof = ProfileInfo("mailing_cof", "ML COF", True) -User.profile_mailing_bda = ProfileInfo("mailing_bda", "ML BdA", True) -User.profile_mailing_bda_revente = ProfileInfo("mailing_bda_revente", +User.profile_mailing_cof = ProfileInfo("cof__mailing", "ML COF", True) +User.profile_mailing_bda = ProfileInfo("cof__mailing_bda", "ML BdA", True) +User.profile_mailing_bda_revente = ProfileInfo("cof__mailing_bda_revente", "ML BdA-R", True) @@ -172,12 +173,14 @@ class UserProfileAdmin(UserAdmin): 'profile_mailing_bda_revente', 'is_cof', 'is_buro', ) list_display_links = ('username', 'email', 'first_name', 'last_name') list_filter = UserAdmin.list_filter \ - + ('profile__is_cof', 'profile__is_buro', 'profile__mailing_cof', - 'profile__mailing_bda') + + ('profile__cof__is_cof', + 'profile__cof__is_buro', + 'profile__cof__mailing', + 'profile__cof__mailing_bda') search_fields = UserAdmin.search_fields + ('profile__phone',) - inlines = [ - CofProfileInline, - ] + # inlines = [ + # CofProfileInline, + # ] staff_fieldsets = [ (None, {'fields': ['username', 'password']}), diff --git a/cof/migrations/0009_generic_profiles.py b/cof/migrations/0009_generic_profiles.py new file mode 100644 index 00000000..c3fb1c13 --- /dev/null +++ b/cof/migrations/0009_generic_profiles.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +def create_profile(apps, schema_editor): + CofProfile = apps.get_model("cof", "CofProfile") + Profile = apps.get_model("gestion", "Profile") + for p in CofProfile.objects.all(): + profile = Profile.objects.create( + id=p.id, + user=p.user, + login_clipper=p.login_clipper, + phone=p.phone, + occupation=p.occupation, + departement=p.departement, + comments=p.comments + ) + p.profile = profile + p.save() + + +def remove_profile(apps, schema_editor): + raise NotImplementedError + + +class Migration(migrations.Migration): + + dependencies = [ + ('gestion', '0001_initial'), + ('cof', '0008_py3'), + ] + + operations = [ + migrations.RenameField( + model_name='cofprofile', + old_name='mailing_cof', + new_name='mailing', + ), + migrations.AddField( + model_name='cofprofile', + name='profile', + field=models.OneToOneField( + to='gestion.Profile', + null=True, + related_name='cof' + ), + preserve_default=False, + ), + migrations.RunPython(create_profile, remove_profile), + migrations.RemoveField( + model_name='cofprofile', + name='comments', + ), + migrations.RemoveField( + model_name='cofprofile', + name='departement', + ), + migrations.RemoveField( + model_name='cofprofile', + name='login_clipper', + ), + migrations.RemoveField( + model_name='cofprofile', + name='occupation', + ), + migrations.RemoveField( + model_name='cofprofile', + name='phone', + ), + migrations.AlterField( + model_name='cofprofile', + name='profile', + field=models.OneToOneField( + to='gestion.Profile', + related_name='cof' + ), + ), + migrations.RemoveField( + model_name='cofprofile', + name='user', + ), + ] diff --git a/cof/models.py b/cof/models.py index 7a9c3fe4..e6c2f3da 100644 --- a/cof/models.py +++ b/cof/models.py @@ -12,20 +12,10 @@ from django.utils.encoding import python_2_unicode_compatible import django.utils.six as six from django.db.models.signals import post_save, post_delete -from .petits_cours_models import choices_length - +from gestion.models import Profile from bda.models import Spectacle -OCCUPATION_CHOICES = ( - ('exterieur', _("Extérieur")), - ('1A', _("1A")), - ('2A', _("2A")), - ('3A', _("3A")), - ('4A', _("4A")), - ('archicube', _("Archicube")), - ('doctorant', _("Doctorant")), - ('CST', _("CST")), -) +from .petits_cours_models import choices_length TYPE_COTIZ_CHOICES = ( ('etudiant', _("Normalien étudiant")), @@ -39,32 +29,26 @@ TYPE_COMMENT_FIELD = ( ) -@python_2_unicode_compatible class CofProfile(models.Model): - user = models.OneToOneField(User, related_name="profile") - login_clipper = models.CharField("Login clipper", max_length=8, blank=True) - is_cof = models.BooleanField("Membre du COF", default=False) + profile = models.OneToOneField(Profile, + on_delete=models.CASCADE, + related_name="cof") + num = models.IntegerField("Numéro d'adhérent", blank=True, default=0) - phone = models.CharField("Téléphone", max_length=20, blank=True) - occupation = models.CharField(_("Occupation"), - default="1A", - choices=OCCUPATION_CHOICES, - max_length=choices_length( - OCCUPATION_CHOICES)) - departement = models.CharField(_("Département"), max_length=50, - blank=True) type_cotiz = models.CharField(_("Type de cotisation"), default="normalien", choices=TYPE_COTIZ_CHOICES, max_length=choices_length( TYPE_COTIZ_CHOICES)) - mailing_cof = models.BooleanField("Recevoir les mails COF", default=False) + mailing = models.BooleanField("Recevoir les mails COF", default=False) + # XXX. remove the following and use django auth. + is_buro = models.BooleanField("Membre du Burô", default=False) + is_cof = models.BooleanField("Membre du COF", default=False) + # XXX. remove the following and put in a BDA profile mailing_bda = models.BooleanField("Recevoir les mails BdA", default=False) mailing_bda_revente = models.BooleanField( "Recevoir les mails de revente de places BdA", default=False) - comments = models.TextField( - "Commentaires visibles par l'utilisateur", blank=True) - is_buro = models.BooleanField("Membre du Burô", default=False) + petits_cours_accept = models.BooleanField( "Recevoir des petits cours", default=False) petits_cours_remarques = models.TextField( @@ -76,7 +60,7 @@ class CofProfile(models.Model): verbose_name_plural = "Profils COF" def __str__(self): - return six.text_type(self.user.username) + return self.user.username @receiver(post_save, sender=User) diff --git a/gestion/migrations/0001_initial.py b/gestion/migrations/0001_initial.py new file mode 100644 index 00000000..daeaa39b --- /dev/null +++ b/gestion/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)), + ('login_clipper', models.CharField(verbose_name='Login clipper', max_length=8, blank=True)), + ('phone', models.CharField(verbose_name='Téléphone', max_length=20, blank=True)), + ('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')), + ], + options={ + 'verbose_name': 'Profil', + 'verbose_name_plural': 'Profils', + }, + ), + ] diff --git a/gestion/models.py b/gestion/models.py index 71a83623..81335ddc 100644 --- a/gestion/models.py +++ b/gestion/models.py @@ -1,3 +1,50 @@ +from django.contrib.auth.models import User from django.db import models +from django.dispatch import receiver +from django.db.models.signals import post_save, post_delete +from django.utils.translation import ugettext_lazy as _ -# Create your models here. +from cof.petits_cours_models import choices_length + +OCCUPATION_CHOICES = ( + ('exterieur', _("Extérieur")), + ('1A', _("1A")), + ('2A', _("2A")), + ('3A', _("3A")), + ('4A', _("4A")), + ('archicube', _("Archicube")), + ('doctorant', _("Doctorant")), + ('CST', _("CST")), +) + +class Profile(models.Model): + user = models.OneToOneField(User, 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"), + default="1A", + choices=OCCUPATION_CHOICES, + max_length=choices_length( + OCCUPATION_CHOICES)) + departement = models.CharField(_("Département"), max_length=50, + blank=True) + comments = models.TextField( + "Commentaires visibles par l'utilisateur", blank=True) + + class Meta: + verbose_name = "Profil" + verbose_name_plural = "Profils" + + def __str__(self): + return self.user.username + +@receiver(post_save, sender=User) +def create_user_profile(sender, instance, created, **kwargs): + if created: + Profile.objects.get_or_create(user=instance) + + +@receiver(post_delete, sender=Profile) +def post_delete_user(sender, instance, *args, **kwargs): + instance.user.delete() diff --git a/kfet/migrations/0048_generic_profiles.py b/kfet/migrations/0048_generic_profiles.py new file mode 100644 index 00000000..e3fda98b --- /dev/null +++ b/kfet/migrations/0048_generic_profiles.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cof', '0009_generic_profiles'), + ('kfet', '0047_auto_20170104_1528'), + ] + + operations = [ + migrations.AlterField( + model_name='account', + name='cofprofile', + field=models.OneToOneField(to='gestion.Profile', related_name='account_kfet'), + ), + ] diff --git a/kfet/models.py b/kfet/models.py index b2e56d49..d161d8ed 100644 --- a/kfet/models.py +++ b/kfet/models.py @@ -3,21 +3,23 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) from builtins import * +from datetime import date, timedelta +import re from django.db import models from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied, ValidationError from django.core.validators import RegexValidator from django.contrib.auth.models import User -from cof.models import CofProfile from django.utils.six.moves import reduce from django.utils import timezone from django.utils.encoding import python_2_unicode_compatible from django.db import transaction from django.db.models import F from django.core.cache import cache -from datetime import date, timedelta -import re + + +from gestion.models import Profile def choices_length(choices): return reduce(lambda m, choice: max(m, len(choice[0])), choices, 0) @@ -28,9 +30,10 @@ def default_promo(): @python_2_unicode_compatible class Account(models.Model): - cofprofile = models.OneToOneField( - CofProfile, on_delete = models.PROTECT, - related_name = "account_kfet") + # XXX. change this to "profile" + cofprofile = models.OneToOneField(Profile, + related_name="account_kfet", + on_delete=models.CASCADE) trigramme = models.CharField( unique = True, max_length = 3,