From 95b492e05d82071fe4740cb76c467496e9d5929c Mon Sep 17 00:00:00 2001 From: Qwann Date: Fri, 30 Sep 2016 20:10:35 +0200 Subject: [PATCH 01/16] =?UTF-8?q?Tous=20les=20mod=C3=A8les=20et=20champs?= =?UTF-8?q?=20sont=20l=C3=A0=20Reste=20=C3=A0=20faire=20les=20=5F=5Fgetatt?= =?UTF-8?q?r=5F=5F=20et=20=5F=5Fsetattr=5F=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- evenementiel/settings_dev.py | 1 + event/__init__.py | 0 event/admin.py | 3 + event/apps.py | 5 ++ event/models.py | 158 +++++++++++++++++++++++++++++++++++ event/tests.py | 3 + event/views.py | 3 + 7 files changed, 173 insertions(+) create mode 100644 event/__init__.py create mode 100644 event/admin.py create mode 100644 event/apps.py create mode 100644 event/models.py create mode 100644 event/tests.py create mode 100644 event/views.py diff --git a/evenementiel/settings_dev.py b/evenementiel/settings_dev.py index 09b66b1..3f52bfc 100644 --- a/evenementiel/settings_dev.py +++ b/evenementiel/settings_dev.py @@ -31,6 +31,7 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ + 'event.apps.EventConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', diff --git a/event/__init__.py b/event/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/event/admin.py b/event/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/event/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/event/apps.py b/event/apps.py new file mode 100644 index 0000000..13b1f16 --- /dev/null +++ b/event/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class EventConfig(AppConfig): + name = 'event' diff --git a/event/models.py b/event/models.py new file mode 100644 index 0000000..9b0b42d --- /dev/null +++ b/event/models.py @@ -0,0 +1,158 @@ +from django.contrib.auth.models import User +from django.utils.translation import ugettext_lazy as _ +from django.core import exceptions +from django.db import models +from re import search as re_search + + +def validate_color(value): + def is_hex_color(s): + return re_search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', s) + if not is_hex_color(value): + raise exceptions.ValidationError( + _("%(value)s n'est pas une couleur"), + code='invalid_choice', + params={'value': value}, + ) + + +class Event(models.Model): + title = models.CharField( + _("Nom de l'évènement"), + max_length=200, + ) + slug = models.SlugField( + _('Identificateur'), + unique=True, + primary_key=True, + help_text=_("Seulement des lettres, des chiffres ou \ + les caractères '_' ou '-'."), + ) + created_by = models.ForeignKey( + User, + related_name=_("created_events"), + editable=False, + ) + creation_date = models.DateTimeField( + _('Date de création'), + auto_now_add=True, + ) + description = models.TextField(_('Description')) + beginning_date = models.DateTimeField(_('Date de début')) + ending_date = models.DateTimeField(_('Date de fin')) + + class Meta: + verbose_name = _("Évènement") + verbose_name_plural = _("Évènements") + + +class Place(models.Model): + name = models.CharField( + _("Nom du lieu"), + max_length=200, + ) + description = models.TextField(blank=True) + + class Meta: + verbose_name = _("Lieu") + verbose_name_plural = _("Lieux") + + +class ActivityTag(models.Model): + name = models.CharField( + _("Nom du tag"), + max_length=200, + ) + is_public = models.BooleanField( + help_text=_("TODO"), + ) + color = models.CharField( + _('Couleur'), + max_length=7, + validators=[validate_color], + ) + + class Meta: + verbose_name = _("Tag") + verbose_name_plural = _("Tags") + + +class ActivityTemplate(models.Model): + title = models.CharField( + _("Nom de l'activité"), + max_length=200, + blank=True, + null=True, + ) + is_public = models.NullBooleanField( + blank=True, + ) + has_perm = models.NullBooleanField( + blank=True, + ) + min_perm = models.PositiveSmallIntegerField( + _('Nombre minimum de permanents'), + blank=True, + null=True, + ) + max_perm = models.PositiveSmallIntegerField( + _('Nombre maximum de permanents'), + blank=True, + null=True, + ) + description = models.TextField( + _('Description'), + help_text=_("Public, Visible par tout le monde."), + blank=True, + null=True, + ) + remarks = models.TextField( + _('Remarques'), + help_text=_("Visible uniquement par les organisateurs"), + blank=True, + null=True, + ) + tags = models.ManyToManyField( + ActivityTag, + related_name=_("activities"), + blank=True, + null=True, + ) + place = models.ManyToManyField( + Place, + related_name=_("activities"), + blank=True, + null=True, + ) + + class Meta: + verbose_name = _("Template activité") + verbose_name_plural = _("Templates activité") + + +class Activity(ActivityTemplate): + parent = models.ForeignKey( + ActivityTemplate, + related_name=_("children"), + ) + staff = models.ManyToManyField( + User, + related_name=_("in_perm_activities"), + blank=True, + ) + # TODO : Utiliser db_constraint ou through + # equipement = models.ManyToManyField(Equipement) + + class Meta: + verbose_name = _("Activité") + verbose_name_plural = _("Activités") + + def __getattr__(self, attrname): + if (attrname == 'parent' + or attrname == 'staff' + or attrname == 'equipement'): + return super(Activity, self).__getattr__(attrname) + elif attrname is None: + return self.parent.attrname + else: + return attrname diff --git a/event/tests.py b/event/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/event/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/event/views.py b/event/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/event/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From 53fda44f8b3f5f236956b5d80ee4b5cc4ad22d92 Mon Sep 17 00:00:00 2001 From: Qwann Date: Sun, 2 Oct 2016 14:19:38 +0200 Subject: [PATCH 02/16] debut des tests --- event/tests.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/event/tests.py b/event/tests.py index 7ce503c..ceaa19c 100644 --- a/event/tests.py +++ b/event/tests.py @@ -1,3 +1,27 @@ +from django.contrib.auth.models import User from django.test import TestCase +from datetime import datetime +from django.utils import timezone +from .models import Event -# Create your tests here. + +class ActivityInheritanceTest(TestCase): + @classmethod + def setUpTestData(cls): + cls.erkan = User.objects.create( + username='enarmanli', + email='erkan.narmanli@ens.fr', + first_name='Erkan', + last_name='Narmanli', + ) + cls.event = Event.objects.create( + title='La Nuit 2042', + slug='nuit42', + created_by=cls.erkan, + creation_date=datetime.now(), + descrition="La nuit c'est lol", + beginning_date=timezone.now() + + datetime.timedelta(days=30), + ending_date=timezone.now() + + datetime.timedelta(days=31), + ) From d4b96f056711b4270f5fb6b27fdcc9bfd32d6bf9 Mon Sep 17 00:00:00 2001 From: Qwann Date: Mon, 3 Oct 2016 00:31:21 +0200 Subject: [PATCH 03/16] =?UTF-8?q?debut=20des=20tests=20ajout=20des=20m?= =?UTF-8?q?=C3=A9thodes=20=5F=5Fstr=5F=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- event/models.py | 35 +++++++++++++++++++++++++---------- event/tests.py | 35 +++++++++++++++++++++++++++++------ 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/event/models.py b/event/models.py index 9b0b42d..ec68e13 100644 --- a/event/models.py +++ b/event/models.py @@ -30,7 +30,7 @@ class Event(models.Model): ) created_by = models.ForeignKey( User, - related_name=_("created_events"), + related_name="created_events", editable=False, ) creation_date = models.DateTimeField( @@ -45,6 +45,9 @@ class Event(models.Model): verbose_name = _("Évènement") verbose_name_plural = _("Évènements") + def __str__(self): + return self.title + class Place(models.Model): name = models.CharField( @@ -57,6 +60,9 @@ class Place(models.Model): verbose_name = _("Lieu") verbose_name_plural = _("Lieux") + def __str__(self): + return self.name + class ActivityTag(models.Model): name = models.CharField( @@ -76,6 +82,9 @@ class ActivityTag(models.Model): verbose_name = _("Tag") verbose_name_plural = _("Tags") + def __str__(self): + return self.name + class ActivityTemplate(models.Model): title = models.CharField( @@ -114,13 +123,13 @@ class ActivityTemplate(models.Model): ) tags = models.ManyToManyField( ActivityTag, - related_name=_("activities"), + related_name="activities", blank=True, null=True, ) place = models.ManyToManyField( Place, - related_name=_("activities"), + related_name="activities", blank=True, null=True, ) @@ -129,15 +138,18 @@ class ActivityTemplate(models.Model): verbose_name = _("Template activité") verbose_name_plural = _("Templates activité") + def __str__(self): + return self.title + class Activity(ActivityTemplate): parent = models.ForeignKey( ActivityTemplate, - related_name=_("children"), + related_name="children", ) staff = models.ManyToManyField( User, - related_name=_("in_perm_activities"), + related_name="in_perm_activities", blank=True, ) # TODO : Utiliser db_constraint ou through @@ -147,12 +159,15 @@ class Activity(ActivityTemplate): verbose_name = _("Activité") verbose_name_plural = _("Activités") + # Si le champ de l'activité n'est pas spécifié + # alors on va chercher celui de self.parent def __getattr__(self, attrname): + attr = super(Activity, self).__getattr__(attrname) if (attrname == 'parent' - or attrname == 'staff' + or attrname == 'staff' or attrname == 'equipement'): - return super(Activity, self).__getattr__(attrname) - elif attrname is None: - return self.parent.attrname + return attr + elif attr is None: + return self.parent.__getattr__(attrname) else: - return attrname + return attr diff --git a/event/tests.py b/event/tests.py index ceaa19c..4aebeaf 100644 --- a/event/tests.py +++ b/event/tests.py @@ -1,8 +1,8 @@ from django.contrib.auth.models import User from django.test import TestCase -from datetime import datetime +from datetime import timedelta from django.utils import timezone -from .models import Event +from .models import Event, ActivityTemplate, Activity, Place class ActivityInheritanceTest(TestCase): @@ -18,10 +18,33 @@ class ActivityInheritanceTest(TestCase): title='La Nuit 2042', slug='nuit42', created_by=cls.erkan, - creation_date=datetime.now(), - descrition="La nuit c'est lol", + creation_date=timezone.now(), + description="La nuit c'est lol", beginning_date=timezone.now() - + datetime.timedelta(days=30), + + timedelta(days=30), ending_date=timezone.now() - + datetime.timedelta(days=31), + + timedelta(days=31), ) + cls.loge = Place.objects.create(name="Loge 45") + cls.permtemp = ActivityTemplate.objects.create( + title="Permanence loge", + # is_public non spécifié + has_perm=False, + description="Les perms c'est lol", + # remark non spécifié + ) + cls.permtemp.place.add(cls.loge) + cls.perm = Activity.objects.create( + parent=cls.permtemp, + # title non spécifié + is_public=True, + # has_perm non spécifié + # description non spécifiée + remarks="lol", + ) + + def test_event_name(self): + self.assertEqual(self.event.title, 'La Nuit 2042') + self.assertEqual(self.loge.name, 'Loge 45') + self.assertEqual(self.permtemp.title, 'Permanence loge') + self.assertEqual(self.permtemp.place.name, 'Loge 45') From 6365704d2dbad51131d7af6d2e72bd3f8c1f24e3 Mon Sep 17 00:00:00 2001 From: Qwann Date: Thu, 13 Oct 2016 11:51:41 +0200 Subject: [PATCH 04/16] models & tests de event normalement c'est fini --- event/models.py | 63 +++++++++++++++++--------- event/tests.py | 115 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 138 insertions(+), 40 deletions(-) diff --git a/event/models.py b/event/models.py index ec68e13..a688096 100644 --- a/event/models.py +++ b/event/models.py @@ -42,8 +42,8 @@ class Event(models.Model): ending_date = models.DateTimeField(_('Date de fin')) class Meta: - verbose_name = _("Évènement") - verbose_name_plural = _("Évènements") + verbose_name = _("évènement") + verbose_name_plural = _("évènements") def __str__(self): return self.title @@ -57,8 +57,8 @@ class Place(models.Model): description = models.TextField(blank=True) class Meta: - verbose_name = _("Lieu") - verbose_name_plural = _("Lieux") + verbose_name = _("lieu") + verbose_name_plural = _("lieux") def __str__(self): return self.name @@ -79,8 +79,8 @@ class ActivityTag(models.Model): ) class Meta: - verbose_name = _("Tag") - verbose_name_plural = _("Tags") + verbose_name = _("tag") + verbose_name_plural = _("tags") def __str__(self): return self.name @@ -93,6 +93,13 @@ class ActivityTemplate(models.Model): blank=True, null=True, ) + # FIXME: voir comment on traite l'héritage de `event` + event = models.ForeignKey( + Event, + related_name="activities", + blank=True, + null=True, + ) is_public = models.NullBooleanField( blank=True, ) @@ -125,18 +132,16 @@ class ActivityTemplate(models.Model): ActivityTag, related_name="activities", blank=True, - null=True, ) place = models.ManyToManyField( Place, related_name="activities", blank=True, - null=True, ) class Meta: - verbose_name = _("Template activité") - verbose_name_plural = _("Templates activité") + verbose_name = _("template activité") + verbose_name_plural = _("templates activité") def __str__(self): return self.title @@ -152,22 +157,40 @@ class Activity(ActivityTemplate): related_name="in_perm_activities", blank=True, ) - # TODO : Utiliser db_constraint ou through # equipement = models.ManyToManyField(Equipement) - class Meta: - verbose_name = _("Activité") - verbose_name_plural = _("Activités") - - # Si le champ de l'activité n'est pas spécifié - # alors on va chercher celui de self.parent - def __getattr__(self, attrname): - attr = super(Activity, self).__getattr__(attrname) + def get_herited(self, attrname): + attr = super(Activity, self).__getattribute__(attrname) if (attrname == 'parent' or attrname == 'staff' or attrname == 'equipement'): return attr + elif (attrname == 'place' or attrname == 'tags'): + if attr.exists(): + return attr + else: + return self.parent.__getattribute__(attrname) elif attr is None: - return self.parent.__getattr__(attrname) + return self.parent.__getattribute__(attrname) else: return attr + + class Meta: + verbose_name = _("activité") + verbose_name_plural = _("activités") + + # Si le champ de l'activité n'est pas spécifié + # alors on va chercher celui de self.parent + # def __getattribute__(self, attrname): + # attr = super(Activity, self).__getattribute__(attrname) + # if (attrname == 'parent' + # or attrname == 'staff' + # or attrname == 'equipement'): + # return attr + # elif attr is None: + # return self.parent.__getattribute__(attrname) + # else: + # return attr + + # def __setattr__(self, name, value): + # self.__dict__[name] = value diff --git a/event/tests.py b/event/tests.py index 4aebeaf..4db30c8 100644 --- a/event/tests.py +++ b/event/tests.py @@ -2,9 +2,11 @@ from django.contrib.auth.models import User from django.test import TestCase from datetime import timedelta from django.utils import timezone -from .models import Event, ActivityTemplate, Activity, Place +from .models import Event, ActivityTemplate, Activity, Place, \ + ActivityTag +# TODO: héritage de `event` ? class ActivityInheritanceTest(TestCase): @classmethod def setUpTestData(cls): @@ -26,25 +28,98 @@ class ActivityInheritanceTest(TestCase): + timedelta(days=31), ) cls.loge = Place.objects.create(name="Loge 45") - cls.permtemp = ActivityTemplate.objects.create( - title="Permanence loge", - # is_public non spécifié - has_perm=False, - description="Les perms c'est lol", - # remark non spécifié - ) - cls.permtemp.place.add(cls.loge) - cls.perm = Activity.objects.create( - parent=cls.permtemp, - # title non spécifié + cls.aqua = Place.objects.create(name="Aquarium") + cls.tag_foo = ActivityTag.objects.create( + name="foo", is_public=True, - # has_perm non spécifié - # description non spécifiée - remarks="lol", + color="#0F0F0F", + ) + cls.tag_bar = ActivityTag.objects.create( + name="bar", + is_public=True, + color="#0F0F0F", ) - def test_event_name(self): - self.assertEqual(self.event.title, 'La Nuit 2042') - self.assertEqual(self.loge.name, 'Loge 45') - self.assertEqual(self.permtemp.title, 'Permanence loge') - self.assertEqual(self.permtemp.place.name, 'Loge 45') + def setUp(self): + self.template_act = ActivityTemplate.objects.create( + # title + # is_public + # has_perm + # min_perm + # max_perm + # description + # remarks + # tags + # place + ) + self.real_act = Activity.objects.create( + # les mêmes plus : + parent=self.template_act, + # staff + ) + + def test_inherites_title(self): + self.template_act.title = "parent" + self.assertEqual(self.real_act.get_herited('title'), "parent") + self.real_act.title = "enfant" + self.assertEqual(self.real_act.get_herited('title'), "enfant") + + def test_inherites_description(self): + self.template_act.description = "parent" + self.assertEqual(self.real_act.get_herited('description'), "parent") + self.real_act.description = "enfant" + self.assertEqual(self.real_act.get_herited('description'), "enfant") + + def test_inherites_remarks(self): + self.template_act.remarks = "parent" + self.assertEqual(self.real_act.get_herited('remarks'), "parent") + self.real_act.remarks = "enfant" + self.assertEqual(self.real_act.get_herited('remarks'), "enfant") + + def test_inherites_is_public(self): + self.template_act.is_public = True + self.assertEqual(self.real_act.get_herited('is_public'), True) + self.real_act.is_public = False + self.assertEqual(self.real_act.get_herited('is_public'), False) + + def test_inherites_has_perm(self): + self.template_act.has_perm = True + self.assertEqual(self.real_act.get_herited('has_perm'), True) + self.real_act.has_perm = False + self.assertEqual(self.real_act.get_herited('has_perm'), False) + + def test_inherites_min_perm(self): + self.template_act.min_perm = 42 + self.assertEqual(self.real_act.get_herited('min_perm'), 42) + self.real_act.min_perm = 1 + self.assertEqual(self.real_act.get_herited('min_perm'), 1) + + def test_inherites_max_perm(self): + self.template_act.max_perm = 42 + self.assertEqual(self.real_act.get_herited('max_perm'), 42) + self.real_act.max_perm = 1 + self.assertEqual(self.real_act.get_herited('max_perm'), 1) + + def test_inherites_place(self): + self.template_act.place.add(self.loge) + self.assertEqual( + self.real_act.get_herited('place').get().name, + "Loge 45" + ) + self.real_act.place.add(self.aqua) + self.assertEqual( + self.real_act.get_herited('place').get().name, + "Aquarium" + ) + + def test_inherites_tags(self): + self.template_act.tags.add(self.tag_foo) + self.assertEqual( + self.real_act.get_herited('tags').get().name, + "foo" + ) + self.real_act.tags.add(self.tag_bar) + self.assertEqual( + self.real_act.get_herited('tags').get().name, + "bar" + ) From dc8fc77130e164a4663db9a859e833f96adc1b4e Mon Sep 17 00:00:00 2001 From: Qwann Date: Thu, 13 Oct 2016 16:24:19 +0200 Subject: [PATCH 05/16] premier jet models equipement --- equipement/__init__.py | 0 equipement/admin.py | 3 ++ equipement/apps.py | 5 +++ equipement/models.py | 73 ++++++++++++++++++++++++++++++++++++++++++ equipement/tests.py | 3 ++ equipement/views.py | 3 ++ event/models.py | 8 ++++- 7 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 equipement/__init__.py create mode 100644 equipement/admin.py create mode 100644 equipement/apps.py create mode 100644 equipement/models.py create mode 100644 equipement/tests.py create mode 100644 equipement/views.py diff --git a/equipement/__init__.py b/equipement/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/equipement/admin.py b/equipement/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/equipement/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/equipement/apps.py b/equipement/apps.py new file mode 100644 index 0000000..7d172de --- /dev/null +++ b/equipement/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class EquipementConfig(AppConfig): + name = 'equipement' diff --git a/equipement/models.py b/equipement/models.py new file mode 100644 index 0000000..70ad3e8 --- /dev/null +++ b/equipement/models.py @@ -0,0 +1,73 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from event.models import Event, Activity + + +class AbstractEquipement(models.Model): + name = models.CharField( + _("Nom du matériel"), + max_length=200, + ) + stock = models.PositieSmallIntegerField(_("Quantité disponible")) + description = models.TextField(_("Description")) + + class Meta: + verbose_name = _("matériel abstrait") + verbose_name_plural = _("matériels abstraits") + + def __str__(self): + return self.name + + +class Equipement(AbstractEquipement): + class Meta: + verbose_name = _("matériel permanent") + verbose_name_plural = _("matériels permanents") + + +class TemporaryEquipement(AbstractEquipement): + event = models.ForeignKey( + Event, + related_name="specific_equipement", + help_text=_("Évènement pour lequel le matériel " + "a été loué ou empreinté ou apporté"), + ) + + class Meta: + verbose_name = _("matériel temporaire") + verbose_name_plural = _("matériels temporaires") + + +class EquipementAttribution(models.Model): + equipement = models.ForeignKey(AbstractEquipement) + activity = models.ForeignKey(Activity) + amount = models.PositiveSmallIntegerField(_("Quantité attribuée")) + remarks = models.TextField("Remarques concernant l'attribution") + + class Meta: + verbose_name = _("attribution de matériel") + verbose_name_plural = _("attributions de matériel") + + def __str__(self): + return self.equipement.name +\ + " (" + self.amout + ") " +\ + " -> " + self.activity.get_herited('title') + + +class EquipementRemark(models.Model): + remark = models.TextField("Remarque sur le matériel") + equipement = models.ForeignKey( + AbstractEquipement, + related_name="remarks", + help_text=_("Matériel concerné par la remarque"), + ) + is_broken = models.BooleanField() + is_lost = models.BooleanField() + + class Meta: + verbose_name = _("remarque sur matériel") + verbose_name_plural = _("remarques sur le matériel") + + def __str__(self): + return self.equipement.name + " : " + self.remark diff --git a/equipement/tests.py b/equipement/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/equipement/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/equipement/views.py b/equipement/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/equipement/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/event/models.py b/event/models.py index a688096..7f51971 100644 --- a/event/models.py +++ b/event/models.py @@ -4,6 +4,8 @@ from django.core import exceptions from django.db import models from re import search as re_search +from equipement.models import AbstractEquipement + def validate_color(value): def is_hex_color(s): @@ -157,7 +159,11 @@ class Activity(ActivityTemplate): related_name="in_perm_activities", blank=True, ) - # equipement = models.ManyToManyField(Equipement) + equipement = models.ManyToManyField( + AbstractEquipement, + related_name="activities", + through="EquipementAttribution", + ) def get_herited(self, attrname): attr = super(Activity, self).__getattribute__(attrname) From d646f77d7e0c0c16d30ba9dc90c13b8344d75ea9 Mon Sep 17 00:00:00 2001 From: Qwann Date: Thu, 13 Oct 2016 16:26:35 +0200 Subject: [PATCH 06/16] heritage de `titre` pour __str__ de Activity --- event/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/event/models.py b/event/models.py index a688096..064d33f 100644 --- a/event/models.py +++ b/event/models.py @@ -179,6 +179,9 @@ class Activity(ActivityTemplate): verbose_name = _("activité") verbose_name_plural = _("activités") + def __str__(self): + return self.get_herited('title') + # Si le champ de l'activité n'est pas spécifié # alors on va chercher celui de self.parent # def __getattribute__(self, attrname): From 6021cc5a332cde4f58aec9f2a69c2d440a1ef2b1 Mon Sep 17 00:00:00 2001 From: Qwann Date: Fri, 14 Oct 2016 13:00:51 +0200 Subject: [PATCH 07/16] middlexare fix --- equipement/__init__.py | 0 equipement/admin.py | 3 -- equipement/apps.py | 5 --- equipement/models.py | 73 ------------------------------------ equipement/tests.py | 3 -- equipement/views.py | 3 -- evenementiel/settings_dev.py | 3 ++ 7 files changed, 3 insertions(+), 87 deletions(-) delete mode 100644 equipement/__init__.py delete mode 100644 equipement/admin.py delete mode 100644 equipement/apps.py delete mode 100644 equipement/models.py delete mode 100644 equipement/tests.py delete mode 100644 equipement/views.py diff --git a/equipement/__init__.py b/equipement/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/equipement/admin.py b/equipement/admin.py deleted file mode 100644 index 8c38f3f..0000000 --- a/equipement/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/equipement/apps.py b/equipement/apps.py deleted file mode 100644 index 7d172de..0000000 --- a/equipement/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class EquipementConfig(AppConfig): - name = 'equipement' diff --git a/equipement/models.py b/equipement/models.py deleted file mode 100644 index 70ad3e8..0000000 --- a/equipement/models.py +++ /dev/null @@ -1,73 +0,0 @@ -from django.db import models -from django.utils.translation import ugettext_lazy as _ - -from event.models import Event, Activity - - -class AbstractEquipement(models.Model): - name = models.CharField( - _("Nom du matériel"), - max_length=200, - ) - stock = models.PositieSmallIntegerField(_("Quantité disponible")) - description = models.TextField(_("Description")) - - class Meta: - verbose_name = _("matériel abstrait") - verbose_name_plural = _("matériels abstraits") - - def __str__(self): - return self.name - - -class Equipement(AbstractEquipement): - class Meta: - verbose_name = _("matériel permanent") - verbose_name_plural = _("matériels permanents") - - -class TemporaryEquipement(AbstractEquipement): - event = models.ForeignKey( - Event, - related_name="specific_equipement", - help_text=_("Évènement pour lequel le matériel " - "a été loué ou empreinté ou apporté"), - ) - - class Meta: - verbose_name = _("matériel temporaire") - verbose_name_plural = _("matériels temporaires") - - -class EquipementAttribution(models.Model): - equipement = models.ForeignKey(AbstractEquipement) - activity = models.ForeignKey(Activity) - amount = models.PositiveSmallIntegerField(_("Quantité attribuée")) - remarks = models.TextField("Remarques concernant l'attribution") - - class Meta: - verbose_name = _("attribution de matériel") - verbose_name_plural = _("attributions de matériel") - - def __str__(self): - return self.equipement.name +\ - " (" + self.amout + ") " +\ - " -> " + self.activity.get_herited('title') - - -class EquipementRemark(models.Model): - remark = models.TextField("Remarque sur le matériel") - equipement = models.ForeignKey( - AbstractEquipement, - related_name="remarks", - help_text=_("Matériel concerné par la remarque"), - ) - is_broken = models.BooleanField() - is_lost = models.BooleanField() - - class Meta: - verbose_name = _("remarque sur matériel") - verbose_name_plural = _("remarques sur le matériel") - - def __str__(self): - return self.equipement.name + " : " + self.remark diff --git a/equipement/tests.py b/equipement/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/equipement/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/equipement/views.py b/equipement/views.py deleted file mode 100644 index 91ea44a..0000000 --- a/equipement/views.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/evenementiel/settings_dev.py b/evenementiel/settings_dev.py index 3f52bfc..4c798b5 100644 --- a/evenementiel/settings_dev.py +++ b/evenementiel/settings_dev.py @@ -31,6 +31,7 @@ ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ + 'equipment.apps.EquipmentConfig', 'event.apps.EventConfig', 'django.contrib.admin', 'django.contrib.auth', @@ -43,6 +44,7 @@ INSTALLED_APPS = [ ] MIDDLEWARE_CLASSES = [ + 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', @@ -131,6 +133,7 @@ USE_TZ = True STATIC_URL = '/static/' + def show_toolbar(request): """ On ne veut pas la vérification de INTERNAL_IPS faite par la debug-toolbar From 3c93b0fa23ad61ec0b5538253a628f1688998781 Mon Sep 17 00:00:00 2001 From: Qwann Date: Fri, 14 Oct 2016 13:02:25 +0200 Subject: [PATCH 08/16] models de equipment done --- equipment/apps.py | 5 +++ equipment/migrations/__init__.py | 0 equipment/models.py | 77 ++++++++++++++++++++++++++++++++ event/migrations/__init__.py | 0 event/models.py | 11 +---- 5 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 equipment/apps.py create mode 100644 equipment/migrations/__init__.py create mode 100644 equipment/models.py create mode 100644 event/migrations/__init__.py diff --git a/equipment/apps.py b/equipment/apps.py new file mode 100644 index 0000000..ac98343 --- /dev/null +++ b/equipment/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class EquipmentConfig(AppConfig): + name = 'equipment' diff --git a/equipment/migrations/__init__.py b/equipment/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/equipment/models.py b/equipment/models.py new file mode 100644 index 0000000..d662367 --- /dev/null +++ b/equipment/models.py @@ -0,0 +1,77 @@ +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from event.models import Event, Activity + + +class AbstractEquipment(models.Model): + name = models.CharField( + _("Nom du matériel"), + max_length=200, + ) + stock = models.PositiveSmallIntegerField(_("Quantité disponible")) + description = models.TextField(_("Description")) + activities = models.ManyToManyField( + Activity, + related_name="equipment", + through="EquipmentAttribution", + ) + + class Meta: + verbose_name = _("matériel abstrait") + verbose_name_plural = _("matériels abstraits") + + def __str__(self): + return self.name + + +class Equipment(AbstractEquipment): + class Meta: + verbose_name = _("matériel permanent") + verbose_name_plural = _("matériels permanents") + + +class TemporaryEquipment(AbstractEquipment): + event = models.ForeignKey( + Event, + related_name="specific_equipment", + help_text=_("Évènement pour lequel le matériel " + "a été loué ou empreinté ou apporté"), + ) + + class Meta: + verbose_name = _("matériel temporaire") + verbose_name_plural = _("matériels temporaires") + + +class EquipmentAttribution(models.Model): + equipment = models.ForeignKey(AbstractEquipment) + activity = models.ForeignKey(Activity) + amount = models.PositiveSmallIntegerField(_("Quantité attribuée")) + remarks = models.TextField("Remarques concernant l'attribution") + + class Meta: + verbose_name = _("attribution de matériel") + verbose_name_plural = _("attributions de matériel") + + def __str__(self): + return self.equipment.name +\ + " (" + self.amout + ") " +\ + " -> " + self.activity.get_herited('title') + + +class EquipmentRemark(models.Model): + remark = models.TextField("Remarque sur le matériel") + equipment = models.ForeignKey( + AbstractEquipment, + related_name="remarks", + help_text=_("Matériel concerné par la remarque"), + ) + is_broken = models.BooleanField() + is_lost = models.BooleanField() + + class Meta: + verbose_name = _("remarque sur matériel") + verbose_name_plural = _("remarques sur le matériel") + + def __str__(self): + return self.equipment.name + " : " + self.remark diff --git a/event/migrations/__init__.py b/event/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/event/models.py b/event/models.py index 2d9d56a..87766e4 100644 --- a/event/models.py +++ b/event/models.py @@ -4,8 +4,6 @@ from django.core import exceptions from django.db import models from re import search as re_search -from equipement.models import AbstractEquipement - def validate_color(value): def is_hex_color(s): @@ -159,17 +157,12 @@ class Activity(ActivityTemplate): related_name="in_perm_activities", blank=True, ) - equipement = models.ManyToManyField( - AbstractEquipement, - related_name="activities", - through="EquipementAttribution", - ) def get_herited(self, attrname): attr = super(Activity, self).__getattribute__(attrname) if (attrname == 'parent' or attrname == 'staff' - or attrname == 'equipement'): + or attrname == 'equipment'): return attr elif (attrname == 'place' or attrname == 'tags'): if attr.exists(): @@ -194,7 +187,7 @@ class Activity(ActivityTemplate): # attr = super(Activity, self).__getattribute__(attrname) # if (attrname == 'parent' # or attrname == 'staff' - # or attrname == 'equipement'): + # or attrname == 'equipment'): # return attr # elif attr is None: # return self.parent.__getattribute__(attrname) From f06ae696e51267eef7daed21c7a6be4ca4d836d2 Mon Sep 17 00:00:00 2001 From: Qwann Date: Mon, 17 Oct 2016 19:40:31 +0200 Subject: [PATCH 09/16] validator modified --- event/models.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/event/models.py b/event/models.py index 064d33f..a93ea3a 100644 --- a/event/models.py +++ b/event/models.py @@ -1,5 +1,6 @@ from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ +from django.core.validators import RegexValidator from django.core import exceptions from django.db import models from re import search as re_search @@ -72,10 +73,16 @@ class ActivityTag(models.Model): is_public = models.BooleanField( help_text=_("TODO"), ) + color_regex = RegexValidator( + regex=r'^#(?:[0-9a-fA-F]{3}){1,2}$', + message="La chaîne de caractère rentrée n'est pas" + "une couleur en hexadécimal.", + ) color = models.CharField( _('Couleur'), max_length=7, - validators=[validate_color], + validators=[color_regex], + help_text="Rentrer une couleur en hexadécimal", ) class Meta: From f3180c0b3ef7e65383b6891f57459a0f3619ab0d Mon Sep 17 00:00:00 2001 From: Qwann Date: Mon, 17 Oct 2016 20:06:00 +0200 Subject: [PATCH 10/16] small fixes --- event/models.py | 5 ++++- event/tests.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/event/models.py b/event/models.py index 87a38d1..d7d8ba9 100644 --- a/event/models.py +++ b/event/models.py @@ -71,7 +71,10 @@ class ActivityTag(models.Model): max_length=200, ) is_public = models.BooleanField( - help_text=_("TODO"), + help_text=_("Sert à faire une distinction dans" + " l'affichage selon que cela soit" + " destiné au public ou à l'équipe" + " organisatrice"), ) color_regex = RegexValidator( regex=r'^#(?:[0-9a-fA-F]{3}){1,2}$', diff --git a/event/tests.py b/event/tests.py index 4db30c8..813aa3b 100644 --- a/event/tests.py +++ b/event/tests.py @@ -1,4 +1,6 @@ from django.contrib.auth.models import User +from django.core.exceptions import ValidationError +from django.db.utils import DataError from django.test import TestCase from datetime import timedelta from django.utils import timezone @@ -123,3 +125,39 @@ class ActivityInheritanceTest(TestCase): self.real_act.get_herited('tags').get().name, "bar" ) + + +class ActivityTagColorTest(TestCase): + def test_positive_color_long(self): + self.tag = ActivityTag.objects.create( + name="bar", + is_public=True, + color="#0F0F0F", + ) + self.tag.full_clean() + + def test_positive_color_small(self): + self.tag = ActivityTag.objects.create( + name="bar", + is_public=True, + color="#0F0", + ) + self.tag.full_clean() + + def test_negative_color_1(self): + self.tag = ActivityTag.objects.create( + name="bar", + is_public=True, + color="#ABCDEG", + ) + with self.assertRaises(ValidationError): + self.tag.full_clean() + + def test_negative_color_2(self): + self.tag = ActivityTag.objects.create( + name="bar", + is_public=True, + color="#ACDE-1", + ) + with self.assertRaises(ValidationError): + self.tag.full_clean() From 926bb664506aa598301162cb3ffa337865a5f69f Mon Sep 17 00:00:00 2001 From: Qwann Date: Fri, 21 Oct 2016 18:49:46 +0200 Subject: [PATCH 11/16] small fixes --- equipment/models.py | 11 ++++++----- event/models.py | 41 ++++++++--------------------------------- event/tests.py | 16 +--------------- 3 files changed, 15 insertions(+), 53 deletions(-) diff --git a/equipment/models.py b/equipment/models.py index d662367..e93cbd3 100644 --- a/equipment/models.py +++ b/equipment/models.py @@ -35,7 +35,7 @@ class TemporaryEquipment(AbstractEquipment): Event, related_name="specific_equipment", help_text=_("Évènement pour lequel le matériel " - "a été loué ou empreinté ou apporté"), + "a été loué ou emprunté ou apporté"), ) class Meta: @@ -54,9 +54,9 @@ class EquipmentAttribution(models.Model): verbose_name_plural = _("attributions de matériel") def __str__(self): - return self.equipment.name +\ - " (" + self.amout + ") " +\ - " -> " + self.activity.get_herited('title') + return "%s (%d) -> %s" % (self.equipment.name, + self.amout, + self.activity.get_herited('title')) class EquipmentRemark(models.Model): @@ -74,4 +74,5 @@ class EquipmentRemark(models.Model): verbose_name_plural = _("remarques sur le matériel") def __str__(self): - return self.equipment.name + " : " + self.remark + return "%s : %s" % (self.equipment.name, + self.remark) diff --git a/event/models.py b/event/models.py index d7d8ba9..9605070 100644 --- a/event/models.py +++ b/event/models.py @@ -1,20 +1,8 @@ from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ from django.core.validators import RegexValidator -from django.core import exceptions +from django.core.exceptions import FieldError from django.db import models -from re import search as re_search - - -def validate_color(value): - def is_hex_color(s): - return re_search(r'^#(?:[0-9a-fA-F]{3}){1,2}$', s) - if not is_hex_color(value): - raise exceptions.ValidationError( - _("%(value)s n'est pas une couleur"), - code='invalid_choice', - params={'value': value}, - ) class Event(models.Model): @@ -26,8 +14,8 @@ class Event(models.Model): _('Identificateur'), unique=True, primary_key=True, - help_text=_("Seulement des lettres, des chiffres ou \ - les caractères '_' ou '-'."), + help_text=_("Seulement des lettres, des chiffres ou" + "les caractères '_' ou '-'."), ) created_by = models.ForeignKey( User, @@ -79,7 +67,7 @@ class ActivityTag(models.Model): color_regex = RegexValidator( regex=r'^#(?:[0-9a-fA-F]{3}){1,2}$', message="La chaîne de caractère rentrée n'est pas" - "une couleur en hexadécimal.", + "une couleur en hexadécimal.", ) color = models.CharField( _('Couleur'), @@ -173,7 +161,10 @@ class Activity(ActivityTemplate): if (attrname == 'parent' or attrname == 'staff' or attrname == 'equipment'): - return attr + raise FieldError( + _("%(attrname)s n'est pas un champ héritable"), + params={'attrname': attrname}, + ) elif (attrname == 'place' or attrname == 'tags'): if attr.exists(): return attr @@ -190,19 +181,3 @@ class Activity(ActivityTemplate): def __str__(self): return self.get_herited('title') - - # Si le champ de l'activité n'est pas spécifié - # alors on va chercher celui de self.parent - # def __getattribute__(self, attrname): - # attr = super(Activity, self).__getattribute__(attrname) - # if (attrname == 'parent' - # or attrname == 'staff' - # or attrname == 'equipment'): - # return attr - # elif attr is None: - # return self.parent.__getattribute__(attrname) - # else: - # return attr - - # def __setattr__(self, name, value): - # self.__dict__[name] = value diff --git a/event/tests.py b/event/tests.py index 813aa3b..e634b82 100644 --- a/event/tests.py +++ b/event/tests.py @@ -1,6 +1,5 @@ from django.contrib.auth.models import User from django.core.exceptions import ValidationError -from django.db.utils import DataError from django.test import TestCase from datetime import timedelta from django.utils import timezone @@ -8,7 +7,6 @@ from .models import Event, ActivityTemplate, Activity, Place, \ ActivityTag -# TODO: héritage de `event` ? class ActivityInheritanceTest(TestCase): @classmethod def setUpTestData(cls): @@ -43,21 +41,9 @@ class ActivityInheritanceTest(TestCase): ) def setUp(self): - self.template_act = ActivityTemplate.objects.create( - # title - # is_public - # has_perm - # min_perm - # max_perm - # description - # remarks - # tags - # place - ) + self.template_act = ActivityTemplate.objects.create() self.real_act = Activity.objects.create( - # les mêmes plus : parent=self.template_act, - # staff ) def test_inherites_title(self): From 87967dbad79ba6bed9e03bf59824958d009ace1d Mon Sep 17 00:00:00 2001 From: Qwann Date: Sat, 18 Feb 2017 01:45:22 +0100 Subject: [PATCH 12/16] adding user model --- .gitignore | 1 + evenementiel/settings_dev.py | 1 + evenementiel/urls.py | 16 +--- user/__init__.py | 0 user/admin.py | 3 + user/apps.py | 5 ++ user/forms.py | 36 ++++++++ user/migrations/0001_initial.py | 26 ++++++ user/migrations/0002_auto_20160616_1803.py | 35 ++++++++ user/migrations/0003_auto_20160623_1603.py | 31 +++++++ user/migrations/0004_auto_20160623_1808.py | 22 +++++ user/migrations/__init__.py | 0 user/models.py | 3 + user/templates/user/base_user.html | 7 ++ user/templates/user/change_pass.html | 4 + user/templates/user/email_password_reset.html | 6 ++ user/templates/user/login.html | 28 ++++++ user/templates/user/password_reset.html | 4 + .../templates/user/subject_password_reset.txt | 1 + user/templates/user/user_form.html | 35 ++++++++ user/tests.py | 3 + user/urls.py | 88 +++++++++++++++++++ user/views.py | 15 ++++ 23 files changed, 355 insertions(+), 15 deletions(-) create mode 100644 user/__init__.py create mode 100644 user/admin.py create mode 100644 user/apps.py create mode 100644 user/forms.py create mode 100644 user/migrations/0001_initial.py create mode 100644 user/migrations/0002_auto_20160616_1803.py create mode 100644 user/migrations/0003_auto_20160623_1603.py create mode 100644 user/migrations/0004_auto_20160623_1808.py create mode 100644 user/migrations/__init__.py create mode 100644 user/models.py create mode 100644 user/templates/user/base_user.html create mode 100644 user/templates/user/change_pass.html create mode 100644 user/templates/user/email_password_reset.html create mode 100644 user/templates/user/login.html create mode 100644 user/templates/user/password_reset.html create mode 100644 user/templates/user/subject_password_reset.txt create mode 100644 user/templates/user/user_form.html create mode 100644 user/tests.py create mode 100644 user/urls.py create mode 100644 user/views.py diff --git a/.gitignore b/.gitignore index 886ee5c..c067e72 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ __pycache__ venv evenementiel/settings.py +.*.swp diff --git a/evenementiel/settings_dev.py b/evenementiel/settings_dev.py index 4c798b5..e6a6909 100644 --- a/evenementiel/settings_dev.py +++ b/evenementiel/settings_dev.py @@ -33,6 +33,7 @@ ALLOWED_HOSTS = [] INSTALLED_APPS = [ 'equipment.apps.EquipmentConfig', 'event.apps.EventConfig', + 'user.apps.UserConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', diff --git a/evenementiel/urls.py b/evenementiel/urls.py index 40462fa..a33af57 100644 --- a/evenementiel/urls.py +++ b/evenementiel/urls.py @@ -1,21 +1,7 @@ -"""evenementiel URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/1.9/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.conf.urls import url, include - 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) -""" from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), + url(r'^user/', include('user.urls')), ] diff --git a/user/__init__.py b/user/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/user/admin.py b/user/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/user/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/user/apps.py b/user/apps.py new file mode 100644 index 0000000..35048d4 --- /dev/null +++ b/user/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class UserConfig(AppConfig): + name = 'user' diff --git a/user/forms.py b/user/forms.py new file mode 100644 index 0000000..bdc86ea --- /dev/null +++ b/user/forms.py @@ -0,0 +1,36 @@ +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from django import forms +from django.conf import settings + + +class CreateUserForm(UserCreationForm): + key = forms.CharField( + label="Clée de sécurité", + widget=forms.PasswordInput, + help_text="Cette clée est fournie par l'administrat-rice-eur " + "du site. Pour en obtenir une veuillez la-le contacter." + ) + error_m = {'wrong_key': "La clef fournie est eronnée."} + + class Meta: + model = User + fields = ('username', 'first_name', 'last_name', + 'email', 'password1', 'password2',) + + def save(self, commit=True): + user = super(CreateUserForm, self).save(commit=False) + user.email = self.cleaned_data["email"] + user.first_name = self.cleaned_data["first_name"] + user.last_name = self.cleaned_data["last_name"] + if commit: + user.save() + return user + + def clean_key(self): + key = self.cleaned_data.get("key") + if key != settings.CREATE_USER_KEY: + raise forms.ValidationError( + self.error_m['wrong_key'], + code='wrong_key') + return key diff --git a/user/migrations/0001_initial.py b/user/migrations/0001_initial.py new file mode 100644 index 0000000..04a012f --- /dev/null +++ b/user/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-06-14 22:17 +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): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Profil', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/user/migrations/0002_auto_20160616_1803.py b/user/migrations/0002_auto_20160616_1803.py new file mode 100644 index 0000000..4193a65 --- /dev/null +++ b/user/migrations/0002_auto_20160616_1803.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-06-16 16:03 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='profil', + name='modif_pad', + field=models.BooleanField(default=False, verbose_name='Modifier tous les pads'), + ), + migrations.AddField( + model_name='profil', + name='read_kholle', + field=models.BooleanField(default=False, verbose_name='Lecture de khôlles'), + ), + migrations.AddField( + model_name='profil', + name='write_kholle', + field=models.BooleanField(default=False, verbose_name='Écriture de khôlles'), + ), + migrations.AddField( + model_name='profil', + name='write_pad', + field=models.BooleanField(default=False, verbose_name='Écrire des pads'), + ), + ] diff --git a/user/migrations/0003_auto_20160623_1603.py b/user/migrations/0003_auto_20160623_1603.py new file mode 100644 index 0000000..401255c --- /dev/null +++ b/user/migrations/0003_auto_20160623_1603.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-06-23 14:03 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0002_auto_20160616_1803'), + ] + + operations = [ + migrations.RemoveField( + model_name='profil', + name='modif_pad', + ), + migrations.RemoveField( + model_name='profil', + name='read_kholle', + ), + migrations.RemoveField( + model_name='profil', + name='write_kholle', + ), + migrations.RemoveField( + model_name='profil', + name='write_pad', + ), + ] diff --git a/user/migrations/0004_auto_20160623_1808.py b/user/migrations/0004_auto_20160623_1808.py new file mode 100644 index 0000000..d2c52e2 --- /dev/null +++ b/user/migrations/0004_auto_20160623_1808.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-06-23 16:08 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0003_auto_20160623_1603'), + ] + + operations = [ + migrations.RemoveField( + model_name='profil', + name='user', + ), + migrations.DeleteModel( + name='Profil', + ), + ] diff --git a/user/migrations/__init__.py b/user/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/user/models.py b/user/models.py new file mode 100644 index 0000000..4e54d78 --- /dev/null +++ b/user/models.py @@ -0,0 +1,3 @@ +from django.db import models +from django.contrib.auth.models import User + diff --git a/user/templates/user/base_user.html b/user/templates/user/base_user.html new file mode 100644 index 0000000..f3e200d --- /dev/null +++ b/user/templates/user/base_user.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block aside %} + {% block user_aside_before %}{% endblock %} +

Les comptes utilisateurs vous donnent accès à la gestion et d'évènements. Vous pouvez vous connecter par le CAS ENS ou via votre compte si vous n'avez pas d'identifiants CAS. Pour créer un tel compte il est nécessaire d'avoir une clée ; merci de contacter un-e administrat-rice-eur pour en obtenir une.

+ {% block user_aside_after %}{% endblock %} +{% endblock %} diff --git a/user/templates/user/change_pass.html b/user/templates/user/change_pass.html new file mode 100644 index 0000000..ff663aa --- /dev/null +++ b/user/templates/user/change_pass.html @@ -0,0 +1,4 @@ +{% extends "user/user_form.html" %} + +{% block action_name %}{% url 'user:password_change' %}{% endblock %} +{% block user_error %}Une erreur s'est produite, veuillez réessayer.{% endblock %} diff --git a/user/templates/user/email_password_reset.html b/user/templates/user/email_password_reset.html new file mode 100644 index 0000000..d9dbd1a --- /dev/null +++ b/user/templates/user/email_password_reset.html @@ -0,0 +1,6 @@ +Bonjour, + +Quelqu'un a demandé à réinitialiser le mot de passe pour le compte utilisateur de qwann.fr utilisant l'adresse mail : {{ email }}. Pour réinitialiser le mot de passe, veuillez suivre le lien suivant : +{{ protocol}}://qwann.fr{% url 'user:password_reset_confirm' uidb64=uid token=token %} + +Merci de ne pas répondre à ce mail. diff --git a/user/templates/user/login.html b/user/templates/user/login.html new file mode 100644 index 0000000..74b291b --- /dev/null +++ b/user/templates/user/login.html @@ -0,0 +1,28 @@ +{% extends "user/user_form.html" %} + +{% block action_name %}{% url 'user:login' %}{% endblock %} +{% block user_error %}L'identitfiant et le mot de passe ne correspondent pas !{% endblock %} + +{% block extra_form_input %} + +{% endblock %} + +{% block user_aside_after %} +
+

Vous n'avez pas de compte utilisateur et vous souhaiteriez en créer un ?

+
+ +
+
+

Vous avez déjà un compte utilisateur et vous avez oublié votre mot de passe ?

+
+ +
+ +{% endblock %} diff --git a/user/templates/user/password_reset.html b/user/templates/user/password_reset.html new file mode 100644 index 0000000..799ab8e --- /dev/null +++ b/user/templates/user/password_reset.html @@ -0,0 +1,4 @@ +{% extends "user/user_form.html" %} + +{% block action_name %}{% url 'user:password_reset' %}{% endblock %} +{% block user_error %}L'identitfiant et le mot de passe ne correspondent pas !{% endblock %} diff --git a/user/templates/user/subject_password_reset.txt b/user/templates/user/subject_password_reset.txt new file mode 100644 index 0000000..68bd26c --- /dev/null +++ b/user/templates/user/subject_password_reset.txt @@ -0,0 +1 @@ +[Qwann.fr] Réinitialisation du mot de passe diff --git a/user/templates/user/user_form.html b/user/templates/user/user_form.html new file mode 100644 index 0000000..b344281 --- /dev/null +++ b/user/templates/user/user_form.html @@ -0,0 +1,35 @@ +{% extends "user/base_user.html" %} +{% load bootstrap %} + +{% block section_title %}{{ sec_title }}{% endblock %} +{% block content %} + {% if form.errors %} +

{% block user_error %}{% endblock %}

+ {% endif %} +
+ {% csrf_token %} +
+ {% for field in form %} + {{ field | bootstrap }} + {% endfor %} +
+
+ + {% block extra_form_input %}{% endblock %} +
+
+ +{% endblock %} + diff --git a/user/tests.py b/user/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/user/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/user/urls.py b/user/urls.py new file mode 100644 index 0000000..2d6ef44 --- /dev/null +++ b/user/urls.py @@ -0,0 +1,88 @@ +from django.conf.urls import url, include +from django.contrib.auth import views as auth_views +from django.core.urlresolvers import reverse_lazy +from event.views import Index #TODO : mettre le vrai home +from user.views import CreateUser + +app_name = 'user' +urlpatterns = [ + # CREATE USER + url('^create/$', CreateUser.as_view(), name='create_user'), + # LOGIN + url('^login/$', + auth_views.login, + { 'template_name': 'user/login.html', + 'extra_context': { + 'sec_title' : 'Connexion', + 'button' : 'Se connecter', + }, + }, + name='login', + ), + # LOGOUT + url('^logout/$', + auth_views.logout, + #TODO : mettre le vrai home + { 'next_page': reverse_lazy('event:index'), + }, + name='logout',), + # PASSWORD_CHANGE + url('^password_change/$', + auth_views.password_change, + { 'template_name': 'user/change_pass.html', + #TODO : mettre le vrai home + 'post_change_redirect': reverse_lazy('event:index'), + 'extra_context': { + 'sec_title' : 'Changement de mot de passe', + 'button' : 'Modifier', + }, + }, + name='password_change'), + # url('^password_change/done/$', name='password_change_done'), + # RESET PASSWORD + url('^password_reset/$', + auth_views.password_reset, + { 'template_name' : 'user/password_reset.html', + 'email_template_name': 'email_password_reset.html', + 'subject_template_name': 'subject_password_reset.txt', + 'post_reset_redirect': reverse_lazy('user:password_reset_done'), + 'extra_context': { + 'sec_title' : 'Demande de nouveau mot de passe', + 'button' : 'Envoyer' + }, + }, + name='password_reset'), + # PASS RESET DONE + url('^password_reset/done/$', + #TODO : mettre le vrai home + Index.as_view(), + name='password_reset_done'), + # PASS RESET CONFIRM + url('^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', + auth_views.password_reset_confirm, + { + 'template_name': 'user/user_form.html', + 'post_reset_redirect' : reverse_lazy('user:password_reset_complete'), + 'extra_context': { + 'sec_title' : 'Changer de mot de passe', + 'button' : 'Changer' + }, + }, + name='password_reset_confirm'), + # PASS RESET COMPLETE + url('^reset/done/$', + #TODO : mettre le vrai home + Index.as_view(), + name='password_reset_complete'), + ] + +# Inclu les vues suivantes : + +# ^login/$ [name='login'] +# ^logout/$ [name='logout'] +# ^password_change/$ [name='password_change'] +# ^password_change/done/$ [name='password_change_done'] +# ^password_reset/$ [name='password_reset'] +# ^password_reset/done/$ [name='password_reset_done'] +# ^reset/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm'] +# ^reset/done/$ [name='password_reset_complete'] diff --git a/user/views.py b/user/views.py new file mode 100644 index 0000000..86160db --- /dev/null +++ b/user/views.py @@ -0,0 +1,15 @@ +from user.forms import CreateUserForm +from django.views.generic.edit import CreateView +from django.contrib.messages.views import SuccessMessageMixin +from django.core.urlresolvers import reverse_lazy + +class CreateUser(SuccessMessageMixin, CreateView): + template_name = 'user/user_form.html' + form_class = CreateUserForm + success_url = reverse_lazy('erkan:index') + success_message = "Votre compte utilisateur a été correctement créé !" + def get_context_data(self, **kwargs): + ctx = super(CreateUser, self).get_context_data(**kwargs) + ctx['button'] = 'Créer' + ctx['sec_title'] = "Création d'utilisateur" + return ctx From c7db0c10b670e56291747c2189d0c667402fdf71 Mon Sep 17 00:00:00 2001 From: Qwann Date: Tue, 21 Feb 2017 17:17:09 +0100 Subject: [PATCH 13/16] include forgotten --- evenementiel/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evenementiel/urls.py b/evenementiel/urls.py index a33af57..4ab8385 100644 --- a/evenementiel/urls.py +++ b/evenementiel/urls.py @@ -1,4 +1,4 @@ -from django.conf.urls import url +from django.conf.urls import url, include from django.contrib import admin urlpatterns = [ From 8055be4c200f686f17270dd21f92e653bb48e4a6 Mon Sep 17 00:00:00 2001 From: Qwann Date: Tue, 21 Feb 2017 17:25:46 +0100 Subject: [PATCH 14/16] fixes --- event/models.py | 4 +--- event/tests.py | 8 ++++---- user/forms.py | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/event/models.py b/event/models.py index 9605070..7723796 100644 --- a/event/models.py +++ b/event/models.py @@ -158,9 +158,7 @@ class Activity(ActivityTemplate): def get_herited(self, attrname): attr = super(Activity, self).__getattribute__(attrname) - if (attrname == 'parent' - or attrname == 'staff' - or attrname == 'equipment'): + if attrname in {"parent", "staff", "equipment"}: raise FieldError( _("%(attrname)s n'est pas un champ héritable"), params={'attrname': attrname}, diff --git a/event/tests.py b/event/tests.py index e634b82..dbf0cf2 100644 --- a/event/tests.py +++ b/event/tests.py @@ -92,24 +92,24 @@ class ActivityInheritanceTest(TestCase): self.template_act.place.add(self.loge) self.assertEqual( self.real_act.get_herited('place').get().name, - "Loge 45" + self.loge ) self.real_act.place.add(self.aqua) self.assertEqual( self.real_act.get_herited('place').get().name, - "Aquarium" + self.aqua ) def test_inherites_tags(self): self.template_act.tags.add(self.tag_foo) self.assertEqual( self.real_act.get_herited('tags').get().name, - "foo" + self.tag_foo ) self.real_act.tags.add(self.tag_bar) self.assertEqual( self.real_act.get_herited('tags').get().name, - "bar" + self.tag_bar ) diff --git a/user/forms.py b/user/forms.py index bdc86ea..7ba4fc3 100644 --- a/user/forms.py +++ b/user/forms.py @@ -6,12 +6,12 @@ from django.conf import settings class CreateUserForm(UserCreationForm): key = forms.CharField( - label="Clée de sécurité", + label="Clef de sécurité", widget=forms.PasswordInput, - help_text="Cette clée est fournie par l'administrat-rice-eur " + help_text="Cette clef est fournie par l'administrat·rice·eur " "du site. Pour en obtenir une veuillez la-le contacter." ) - error_m = {'wrong_key': "La clef fournie est eronnée."} + error_m = {'wrong_key': "La clef fournie est erronée."} class Meta: model = User From e72969e99ba22515b72f6109e74edd924ae71afb Mon Sep 17 00:00:00 2001 From: Qwann Date: Tue, 21 Feb 2017 21:16:50 +0100 Subject: [PATCH 15/16] initial migrations --- equipment/migrations/0001_initial.py | 95 ++++++++++++++++++++++ event/migrations/0001_initial.py | 114 +++++++++++++++++++++++++++ event/views.py | 5 +- 3 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 equipment/migrations/0001_initial.py create mode 100644 event/migrations/0001_initial.py diff --git a/equipment/migrations/0001_initial.py b/equipment/migrations/0001_initial.py new file mode 100644 index 0000000..ccc9e91 --- /dev/null +++ b/equipment/migrations/0001_initial.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-02-21 20:14 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('event', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='AbstractEquipment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, verbose_name='Nom du matériel')), + ('stock', models.PositiveSmallIntegerField(verbose_name='Quantité disponible')), + ('description', models.TextField(verbose_name='Description')), + ], + options={ + 'verbose_name': 'matériel abstrait', + 'verbose_name_plural': 'matériels abstraits', + }, + ), + migrations.CreateModel( + name='EquipmentAttribution', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.PositiveSmallIntegerField(verbose_name='Quantité attribuée')), + ('remarks', models.TextField(verbose_name="Remarques concernant l'attribution")), + ('activity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='event.Activity')), + ], + options={ + 'verbose_name': 'attribution de matériel', + 'verbose_name_plural': 'attributions de matériel', + }, + ), + migrations.CreateModel( + name='EquipmentRemark', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('remark', models.TextField(verbose_name='Remarque sur le matériel')), + ('is_broken', models.BooleanField()), + ('is_lost', models.BooleanField()), + ], + options={ + 'verbose_name': 'remarque sur matériel', + 'verbose_name_plural': 'remarques sur le matériel', + }, + ), + migrations.CreateModel( + name='Equipment', + fields=[ + ('abstractequipment_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='equipment.AbstractEquipment')), + ], + options={ + 'verbose_name': 'matériel permanent', + 'verbose_name_plural': 'matériels permanents', + }, + bases=('equipment.abstractequipment',), + ), + migrations.CreateModel( + name='TemporaryEquipment', + fields=[ + ('abstractequipment_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='equipment.AbstractEquipment')), + ('event', models.ForeignKey(help_text='Évènement pour lequel le matériel a été loué ou emprunté ou apporté', on_delete=django.db.models.deletion.CASCADE, related_name='specific_equipment', to='event.Event')), + ], + options={ + 'verbose_name': 'matériel temporaire', + 'verbose_name_plural': 'matériels temporaires', + }, + bases=('equipment.abstractequipment',), + ), + migrations.AddField( + model_name='equipmentremark', + name='equipment', + field=models.ForeignKey(help_text='Matériel concerné par la remarque', on_delete=django.db.models.deletion.CASCADE, related_name='remarks', to='equipment.AbstractEquipment'), + ), + migrations.AddField( + model_name='equipmentattribution', + name='equipment', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='equipment.AbstractEquipment'), + ), + migrations.AddField( + model_name='abstractequipment', + name='activities', + field=models.ManyToManyField(related_name='equipment', through='equipment.EquipmentAttribution', to='event.Activity'), + ), + ] diff --git a/event/migrations/0001_initial.py b/event/migrations/0001_initial.py new file mode 100644 index 0000000..067d32d --- /dev/null +++ b/event/migrations/0001_initial.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-02-21 20:14 +from __future__ import unicode_literals + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='ActivityTag', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, verbose_name='Nom du tag')), + ('is_public', models.BooleanField(help_text="Sert à faire une distinction dans l'affichage selon que cela soit destiné au public ou à l'équipe organisatrice")), + ('color', models.CharField(help_text='Rentrer une couleur en hexadécimal', max_length=7, validators=[django.core.validators.RegexValidator(message="La chaîne de caractère rentrée n'est pasune couleur en hexadécimal.", regex='^#(?:[0-9a-fA-F]{3}){1,2}$')], verbose_name='Couleur')), + ], + options={ + 'verbose_name': 'tag', + 'verbose_name_plural': 'tags', + }, + ), + migrations.CreateModel( + name='ActivityTemplate', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(blank=True, max_length=200, null=True, verbose_name="Nom de l'activité")), + ('is_public', models.NullBooleanField()), + ('has_perm', models.NullBooleanField()), + ('min_perm', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Nombre minimum de permanents')), + ('max_perm', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='Nombre maximum de permanents')), + ('description', models.TextField(blank=True, help_text='Public, Visible par tout le monde.', null=True, verbose_name='Description')), + ('remarks', models.TextField(blank=True, help_text='Visible uniquement par les organisateurs', null=True, verbose_name='Remarques')), + ], + options={ + 'verbose_name': 'template activité', + 'verbose_name_plural': 'templates activité', + }, + ), + migrations.CreateModel( + name='Event', + fields=[ + ('title', models.CharField(max_length=200, verbose_name="Nom de l'évènement")), + ('slug', models.SlugField(help_text="Seulement des lettres, des chiffres oules caractères '_' ou '-'.", primary_key=True, serialize=False, unique=True, verbose_name='Identificateur')), + ('creation_date', models.DateTimeField(auto_now_add=True, verbose_name='Date de création')), + ('description', models.TextField(verbose_name='Description')), + ('beginning_date', models.DateTimeField(verbose_name='Date de début')), + ('ending_date', models.DateTimeField(verbose_name='Date de fin')), + ('created_by', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='created_events', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'évènement', + 'verbose_name_plural': 'évènements', + }, + ), + migrations.CreateModel( + name='Place', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=200, verbose_name='Nom du lieu')), + ('description', models.TextField(blank=True)), + ], + options={ + 'verbose_name': 'lieu', + 'verbose_name_plural': 'lieux', + }, + ), + migrations.CreateModel( + name='Activity', + fields=[ + ('activitytemplate_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='event.ActivityTemplate')), + ], + options={ + 'verbose_name': 'activité', + 'verbose_name_plural': 'activités', + }, + bases=('event.activitytemplate',), + ), + migrations.AddField( + model_name='activitytemplate', + name='event', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='event.Event'), + ), + migrations.AddField( + model_name='activitytemplate', + name='place', + field=models.ManyToManyField(blank=True, related_name='activities', to='event.Place'), + ), + migrations.AddField( + model_name='activitytemplate', + name='tags', + field=models.ManyToManyField(blank=True, related_name='activities', to='event.ActivityTag'), + ), + migrations.AddField( + model_name='activity', + name='parent', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='children', to='event.ActivityTemplate'), + ), + migrations.AddField( + model_name='activity', + name='staff', + field=models.ManyToManyField(blank=True, related_name='in_perm_activities', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/event/views.py b/event/views.py index 91ea44a..37b0398 100644 --- a/event/views.py +++ b/event/views.py @@ -1,3 +1,6 @@ from django.shortcuts import render +from django.views.generic import TemplateView -# Create your views here. + +class Index(TemplateView): + template_name="event/index.html" From 01014c68de1b77da830a2eb70429ae3176e2e106 Mon Sep 17 00:00:00 2001 From: Qwann Date: Sun, 5 Mar 2017 13:25:04 +0100 Subject: [PATCH 16/16] test fixed --- event/tests.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/event/tests.py b/event/tests.py index dbf0cf2..38b2add 100644 --- a/event/tests.py +++ b/event/tests.py @@ -91,24 +91,24 @@ class ActivityInheritanceTest(TestCase): def test_inherites_place(self): self.template_act.place.add(self.loge) self.assertEqual( - self.real_act.get_herited('place').get().name, + self.real_act.get_herited('place').get(), self.loge ) self.real_act.place.add(self.aqua) self.assertEqual( - self.real_act.get_herited('place').get().name, + self.real_act.get_herited('place').get(), self.aqua ) def test_inherites_tags(self): self.template_act.tags.add(self.tag_foo) self.assertEqual( - self.real_act.get_herited('tags').get().name, + self.real_act.get_herited('tags').get(), self.tag_foo ) self.real_act.tags.add(self.tag_bar) self.assertEqual( - self.real_act.get_herited('tags').get().name, + self.real_act.get_herited('tags').get(), self.tag_bar )