From 32feb46f886591cb310eb814e989eabcd32da05c Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 19:17:01 +0300 Subject: [PATCH 01/15] Add occupation model to function as history of roles --- webapp/admin.py | 3 +- webapp/migrations/0055_auto_20190926_1850.py | 31 ++++++++++++ webapp/migrations/0056_auto_20190926_1857.py | 51 +++++++++++++++++++ webapp/migrations/0057_auto_20190926_1915.py | 18 +++++++ webapp/models.py | 52 +++++++++++++++++--- 5 files changed, 147 insertions(+), 8 deletions(-) create mode 100644 webapp/migrations/0055_auto_20190926_1850.py create mode 100644 webapp/migrations/0056_auto_20190926_1857.py create mode 100644 webapp/migrations/0057_auto_20190926_1915.py diff --git a/webapp/admin.py b/webapp/admin.py index 2059a1d..dd0c36f 100644 --- a/webapp/admin.py +++ b/webapp/admin.py @@ -1,7 +1,7 @@ """File containing webapp app admin registers.""" from django.contrib import admin -from webapp.models import Official, Role, Committee +from webapp.models import Official, Role, Committee, Occupation from webapp.models import Feed, Tag, BaseFeed, Event, Signup, SignupForm, TemplateQuestion from modeltranslation.admin import TranslationAdmin from django.contrib.auth.models import Permission @@ -17,5 +17,6 @@ admin.site.register(SignupForm, TranslationAdmin) admin.site.register(Signup, TranslationAdmin) admin.site.register(TemplateQuestion, TranslationAdmin) admin.site.register(Official) +admin.site.register(Occupation) admin.site.register(Role) admin.site.register(Committee) diff --git a/webapp/migrations/0055_auto_20190926_1850.py b/webapp/migrations/0055_auto_20190926_1850.py new file mode 100644 index 0000000..a1fb4ff --- /dev/null +++ b/webapp/migrations/0055_auto_20190926_1850.py @@ -0,0 +1,31 @@ +# Generated by Django 2.1.5 on 2019-09-26 15:50 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0054_auto_20190313_1642'), + ] + + operations = [ + migrations.CreateModel( + name='Occupation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_date', models.DateField(verbose_name='Start date')), + ('end_date', models.DateField(verbose_name='End date')), + ], + options={ + 'verbose_name': 'Occupation', + 'verbose_name_plural': 'Occupations', + }, + ), + migrations.DeleteModel( + name='official' + ) + ] diff --git a/webapp/migrations/0056_auto_20190926_1857.py b/webapp/migrations/0056_auto_20190926_1857.py new file mode 100644 index 0000000..6f99cba --- /dev/null +++ b/webapp/migrations/0056_auto_20190926_1857.py @@ -0,0 +1,51 @@ +# Generated by Django 2.1.5 on 2019-09-26 15:57 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import phonenumber_field.modelfields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0055_auto_20190926_1850'), + ] + + operations = [ + migrations.CreateModel( + name='Official', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, verbose_name='Phone number')), + ], + options={ + 'verbose_name': 'Official', + 'verbose_name_plural': 'Officials', + }, + ), + migrations.RemoveField( + model_name='role', + name='end_date', + ), + migrations.RemoveField( + model_name='role', + name='start_date', + ), + migrations.AddField( + model_name='occupation', + name='occupation', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + migrations.AddField( + model_name='official', + name='role_history', + field=models.ManyToManyField(to='webapp.Occupation'), + ), + migrations.AddField( + model_name='official', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/webapp/migrations/0057_auto_20190926_1915.py b/webapp/migrations/0057_auto_20190926_1915.py new file mode 100644 index 0000000..ae2c01f --- /dev/null +++ b/webapp/migrations/0057_auto_20190926_1915.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.5 on 2019-09-26 16:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0056_auto_20190926_1857'), + ] + + operations = [ + migrations.AlterField( + model_name='official', + name='role_history', + field=models.ManyToManyField(blank=True, to='webapp.Occupation'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 348d8d7..9325702 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -4,9 +4,10 @@ from django.db import models from django.utils import timezone # from datetime import timedelta from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver from webapp.utils import month_from_now from django.utils.translation import ugettext_lazy as _ -# from django.contrib.auth.models import User from auditlog.registry import auditlog from phonenumber_field.modelfields import PhoneNumberField # from django.contrib.postgres.fields import JSONField @@ -163,7 +164,7 @@ class Role(PresetRole): Model for Role. Model representing an active or historical occupation - in an official's history. + in the guild. """ class Meta: @@ -172,12 +173,32 @@ class Role(PresetRole): verbose_name = _('Role') verbose_name_plural = _('Roles') - start_date = models.DateField(_('Start date')) - end_date = models.DateField(_('End date')) committee = models.ForeignKey('Committee', related_name='roles', on_delete=models.SET_NULL, null=True) + def __str__(self): + return '{} (Hallitus: {}) ({})'.format(self.name, _("Yes") if self.is_board else _("No"), self.committee) -class Official(User): + +class Occupation(models.Model): + """ + Model for a occupation in guild. + + Model links Official into a role he/she has or has had in the guild. + """ + + class Meta: + verbose_name = _('Occupation') + verbose_name_plural = _('Occupations') + + start_date = models.DateField(_('Start date')) + end_date = models.DateField(_('End date')) + occupation = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) + + def __str__(self): + return '{}: {} - {}'.format(self.occupation.name, self.start_date, self.end_date) + + +class Official(models.Model): """Model representing a guild official.""" class Meta: @@ -186,11 +207,28 @@ class Official(User): verbose_name = _('Official') verbose_name_plural = _('Officials') + user = models.OneToOneField(User, on_delete=models.CASCADE) + phone_number = PhoneNumberField(_('Phone number')) - role = models.ManyToManyField('Role', related_name='official') + role_history = models.ManyToManyField('Occupation', blank=True) + + @property + def current_roles(self): + return self.role_history.all().filter(end_date__gte=timezone.now()).filter(start_date__lte=timezone.now()) def __str__(self): - return '{} {}'.format(self.first_name, self.last_name) + return '{} {}'.format(self.user.first_name, self.user.last_name) + + +@receiver(post_save, sender=User) +def create_user_profile(sender, instance, created, **kwargs): + if created: + Official.objects.create(user=instance) + + +@receiver(post_save, sender=User) +def save_user_profile(sender, instance, **kwargs): + instance.official.save() auditlog.register(Tag) From 22371b8f15366f8cc4aac4b94b95adcb8680ae25 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 19:22:11 +0300 Subject: [PATCH 02/15] Locales --- locale/en/LC_MESSAGES/django.po | 87 ++++++++++++++++++-------------- locale/fi/LC_MESSAGES/django.po | 88 +++++++++++++++++++-------------- 2 files changed, 101 insertions(+), 74 deletions(-) diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po index f0ed178..81e9aa9 100644 --- a/locale/en/LC_MESSAGES/django.po +++ b/locale/en/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-16 19:33+0300\n" +"POT-Creation-Date: 2019-09-26 19:19+0300\n" "PO-Revision-Date: 2017-11-02 23:09+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -37,7 +37,7 @@ msgstr "Sössö articles" msgid "Today's lunch" msgstr "" -#: infoscreen/models.py:212 webapp/models.py:74 +#: infoscreen/models.py:212 webapp/models.py:75 msgid "Events" msgstr "Events" @@ -113,7 +113,7 @@ msgid "Delete" msgstr "Delete" #: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:56 -#: kaehmy/templates/list.html:36 webapp/models.py:125 webapp/models.py:154 +#: kaehmy/templates/list.html:36 webapp/models.py:126 webapp/models.py:155 msgid "Name" msgstr "Name" @@ -263,7 +263,7 @@ msgstr "" msgid "Category" msgstr "" -#: kaehmy/models.py:39 webapp/models.py:136 +#: kaehmy/models.py:39 webapp/models.py:137 msgid "Description" msgstr "Description" @@ -311,7 +311,7 @@ msgstr "Kaehmy application" msgid "Kaehmylomakkeet" msgstr "Kaehmy applications" -#: kaehmy/models.py:98 webapp/models.py:189 +#: kaehmy/models.py:98 webapp/models.py:212 msgid "Phone number" msgstr "" @@ -327,7 +327,7 @@ msgstr "" msgid "Custom role name" msgstr "" -#: kaehmy/models.py:104 webapp/models.py:126 +#: kaehmy/models.py:104 webapp/models.py:127 msgid "Board member" msgstr "Board member" @@ -351,7 +351,7 @@ msgstr "" msgid "Telegram channels" msgstr "" -#: kaehmy/tables.py:13 webapp/models.py:173 +#: kaehmy/tables.py:13 webapp/models.py:174 msgid "Roles" msgstr "" @@ -1111,111 +1111,127 @@ msgstr "Go" msgid "Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry" -#: webapp/models.py:17 +#: webapp/models.py:18 msgid "Webapp" msgstr "Webapp" -#: webapp/models.py:28 +#: webapp/models.py:29 msgid "Tag" msgstr "Tag" -#: webapp/models.py:29 +#: webapp/models.py:30 msgid "Tags" msgstr "Tags" -#: webapp/models.py:32 +#: webapp/models.py:33 msgid "Tag: {}" msgstr "Tag: {}" -#: webapp/models.py:53 +#: webapp/models.py:54 msgid "Feed: {}" msgstr "Feed: {}" -#: webapp/models.py:56 +#: webapp/models.py:57 msgid "Feed" msgstr "" -#: webapp/models.py:57 +#: webapp/models.py:58 msgid "Feeds" msgstr "" -#: webapp/models.py:70 +#: webapp/models.py:71 msgid "Event: {}" msgstr "" -#: webapp/models.py:73 +#: webapp/models.py:74 msgid "Event" msgstr "" -#: webapp/models.py:84 +#: webapp/models.py:85 msgid "Template questions: {}" msgstr "" -#: webapp/models.py:87 +#: webapp/models.py:88 msgid "Template question" msgstr "" -#: webapp/models.py:88 +#: webapp/models.py:89 msgid "Template questions" msgstr "" -#: webapp/models.py:102 +#: webapp/models.py:103 msgid "#{} {}" msgstr "" -#: webapp/models.py:105 +#: webapp/models.py:106 msgid "Signup form" msgstr "" -#: webapp/models.py:106 +#: webapp/models.py:107 msgid "Signup forms" msgstr "" -#: webapp/models.py:115 +#: webapp/models.py:116 msgid "Sign-ups: {}" msgstr "" -#: webapp/models.py:118 +#: webapp/models.py:119 msgid "Sign-up" msgstr "" -#: webapp/models.py:119 +#: webapp/models.py:120 msgid "Sign-ups" msgstr "" -#: webapp/models.py:130 +#: webapp/models.py:131 msgid "board member" msgstr "board member" -#: webapp/models.py:148 +#: webapp/models.py:149 msgid "Committee" msgstr "" -#: webapp/models.py:149 +#: webapp/models.py:150 msgid "Committees" msgstr "" -#: webapp/models.py:152 +#: webapp/models.py:153 msgid "Committee: {}" msgstr "" -#: webapp/models.py:172 +#: webapp/models.py:173 msgid "Role" msgstr "" -#: webapp/models.py:175 +#: webapp/models.py:179 +msgid "Yes" +msgstr "" + +#: webapp/models.py:179 +msgid "No" +msgstr "" + +#: webapp/models.py:190 +msgid "Occupation" +msgstr "Occupation" + +#: webapp/models.py:191 +msgid "Occupations" +msgstr "Occupations" + +#: webapp/models.py:193 msgid "Start date" msgstr "" -#: webapp/models.py:176 +#: webapp/models.py:194 msgid "End date" msgstr "" -#: webapp/models.py:186 +#: webapp/models.py:207 msgid "Official" msgstr "" -#: webapp/models.py:187 +#: webapp/models.py:208 msgid "Officials" msgstr "" @@ -1340,6 +1356,3 @@ msgstr "Corporate" #~ msgid "Missing \"textfield\" POST request field" #~ msgstr "Missing \"textfield\" POST request field" - -#~ msgid "Options" -#~ msgstr "Options" diff --git a/locale/fi/LC_MESSAGES/django.po b/locale/fi/LC_MESSAGES/django.po index 25eee0e..7a39bc6 100644 --- a/locale/fi/LC_MESSAGES/django.po +++ b/locale/fi/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-09-16 19:33+0300\n" +"POT-Creation-Date: 2019-09-26 19:19+0300\n" "PO-Revision-Date: 2017-11-02 23:04+0200\n" "Last-Translator: \n" "Language-Team: \n" @@ -38,7 +38,7 @@ msgstr "Sössön artikkelit" msgid "Today's lunch" msgstr "Päivän lounas" -#: infoscreen/models.py:212 webapp/models.py:74 +#: infoscreen/models.py:212 webapp/models.py:75 msgid "Events" msgstr "Tapahtumat" @@ -114,7 +114,7 @@ msgid "Delete" msgstr "Poista" #: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:56 -#: kaehmy/templates/list.html:36 webapp/models.py:125 webapp/models.py:154 +#: kaehmy/templates/list.html:36 webapp/models.py:126 webapp/models.py:155 msgid "Name" msgstr "Nimi" @@ -264,7 +264,7 @@ msgstr "Muut" msgid "Category" msgstr "Kategoria" -#: kaehmy/models.py:39 webapp/models.py:136 +#: kaehmy/models.py:39 webapp/models.py:137 msgid "Description" msgstr "Kuvaus" @@ -312,7 +312,7 @@ msgstr "Kaehmylomake" msgid "Kaehmylomakkeet" msgstr "Kaehmylomakkeet" -#: kaehmy/models.py:98 webapp/models.py:189 +#: kaehmy/models.py:98 webapp/models.py:212 msgid "Phone number" msgstr "Puhelinnumero" @@ -328,7 +328,7 @@ msgstr "Teksti" msgid "Custom role name" msgstr "Uusi virka" -#: kaehmy/models.py:104 webapp/models.py:126 +#: kaehmy/models.py:104 webapp/models.py:127 msgid "Board member" msgstr "Hallituksen jäsen" @@ -352,7 +352,7 @@ msgstr "Telegram-kanava" msgid "Telegram channels" msgstr "Telegram-kanavat" -#: kaehmy/tables.py:13 webapp/models.py:173 +#: kaehmy/tables.py:13 webapp/models.py:174 msgid "Roles" msgstr "Roolit" @@ -767,10 +767,8 @@ msgid "" msgstr "" #: members/templates/email_application_submit.html:15 -#, fuzzy -#| msgid "Muista myös maksaa jäsenmaksusi!" msgid "Muistathan maksaa jäsenmaksun! Alla maksutiedot" -msgstr "Muista myös maksaa jäsenmaksusi!" +msgstr "Muistathan maksaa jäsenmaksun! Alla maksutiedot" #: members/templates/email_application_submit.html:17 msgid "Saaja" @@ -1101,111 +1099,127 @@ msgstr "Vaihda" msgid "Aalto-yliopiston Sähköinsinöörikilta ry" msgstr "Aalto-yliopiston Sähköinsinöörikilta ry" -#: webapp/models.py:17 +#: webapp/models.py:18 msgid "Webapp" msgstr "Nettisivut" -#: webapp/models.py:28 +#: webapp/models.py:29 msgid "Tag" msgstr "Tunniste" -#: webapp/models.py:29 +#: webapp/models.py:30 msgid "Tags" msgstr "Tunnisteet" -#: webapp/models.py:32 +#: webapp/models.py:33 msgid "Tag: {}" msgstr "Tunniste: {}" -#: webapp/models.py:53 +#: webapp/models.py:54 msgid "Feed: {}" msgstr "Uutinen: {}" -#: webapp/models.py:56 +#: webapp/models.py:57 msgid "Feed" msgstr "Uutinen" -#: webapp/models.py:57 +#: webapp/models.py:58 msgid "Feeds" msgstr "Uutiset" -#: webapp/models.py:70 +#: webapp/models.py:71 msgid "Event: {}" msgstr "Tapahtuma: {}" -#: webapp/models.py:73 +#: webapp/models.py:74 msgid "Event" msgstr "Tapahtuma" -#: webapp/models.py:84 +#: webapp/models.py:85 msgid "Template questions: {}" msgstr "Vakiokysymykset: {}" -#: webapp/models.py:87 +#: webapp/models.py:88 msgid "Template question" msgstr "Vakiokysymys" -#: webapp/models.py:88 +#: webapp/models.py:89 msgid "Template questions" msgstr "Vakiokysymykset" -#: webapp/models.py:102 +#: webapp/models.py:103 msgid "#{} {}" msgstr "" -#: webapp/models.py:105 +#: webapp/models.py:106 msgid "Signup form" msgstr "Ilmoittautumislomake" -#: webapp/models.py:106 +#: webapp/models.py:107 msgid "Signup forms" msgstr "Ilmoittautumislomakkeet" -#: webapp/models.py:115 +#: webapp/models.py:116 msgid "Sign-ups: {}" msgstr "Ilmoittautumiset: {}" -#: webapp/models.py:118 +#: webapp/models.py:119 msgid "Sign-up" msgstr "Ilmoittautuminen" -#: webapp/models.py:119 +#: webapp/models.py:120 msgid "Sign-ups" msgstr "Ilmoittautumiset" -#: webapp/models.py:130 +#: webapp/models.py:131 msgid "board member" msgstr "hallituksen jäsen" -#: webapp/models.py:148 +#: webapp/models.py:149 msgid "Committee" msgstr "Toimikunta" -#: webapp/models.py:149 +#: webapp/models.py:150 msgid "Committees" msgstr "Toimikunnat" -#: webapp/models.py:152 +#: webapp/models.py:153 msgid "Committee: {}" msgstr "Toimikunta: {}" -#: webapp/models.py:172 +#: webapp/models.py:173 msgid "Role" msgstr "Rooli" -#: webapp/models.py:175 +#: webapp/models.py:179 +msgid "Yes" +msgstr "" + +#: webapp/models.py:179 +msgid "No" +msgstr "" + +#: webapp/models.py:190 +msgid "Occupation" +msgstr "Virka" + +#: webapp/models.py:191 +msgid "Occupations" +msgstr "Virat" + +#: webapp/models.py:193 msgid "Start date" msgstr "Alkupäivämäärä" -#: webapp/models.py:176 +#: webapp/models.py:194 msgid "End date" msgstr "Loppupäivämäärä" -#: webapp/models.py:186 +#: webapp/models.py:207 msgid "Official" msgstr "Toimihenkilö" -#: webapp/models.py:187 +#: webapp/models.py:208 msgid "Officials" msgstr "Toimihenkilöt" From e365c394d86b79ac60a22ee07b978accd8b639c4 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 20:16:24 +0300 Subject: [PATCH 03/15] Fix user creation receiver at official creation --- webapp/migrations/0058_auto_20190926_2010.py | 31 ++++++++++++++++++++ webapp/models.py | 23 +++++++++++---- webapp/serializers.py | 10 ++++++- 3 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 webapp/migrations/0058_auto_20190926_2010.py diff --git a/webapp/migrations/0058_auto_20190926_2010.py b/webapp/migrations/0058_auto_20190926_2010.py new file mode 100644 index 0000000..e7230cd --- /dev/null +++ b/webapp/migrations/0058_auto_20190926_2010.py @@ -0,0 +1,31 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0057_auto_20190926_1915'), + ] + + operations = [ + migrations.AddField( + model_name='official', + name='email', + field=models.EmailField(default='asd@asd.fi', max_length=254, verbose_name='Email address'), + preserve_default=False, + ), + migrations.AddField( + model_name='official', + name='first_name', + field=models.CharField(default='asd', max_length=30, verbose_name='First name'), + preserve_default=False, + ), + migrations.AddField( + model_name='official', + name='last_name', + field=models.CharField(default='asd', max_length=150, verbose_name='Last name'), + preserve_default=False, + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 9325702..c3fd53d 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -209,6 +209,9 @@ class Official(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) + first_name = models.CharField(_('First name'), max_length=30) + last_name = models.CharField(_('Last name'), max_length=150) + email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) role_history = models.ManyToManyField('Occupation', blank=True) @@ -216,19 +219,29 @@ class Official(models.Model): def current_roles(self): return self.role_history.all().filter(end_date__gte=timezone.now()).filter(start_date__lte=timezone.now()) + @property + def roles_of_year(self, year): + return self.role_history.all().filter(end_date__gte=timezone.datetime(year, 1, 1)).filter(start_date__lte=timezone.datetime(year, 12, 31)) + def __str__(self): - return '{} {}'.format(self.user.first_name, self.user.last_name) + return '{} {}'.format(self.first_name, self.last_name) -@receiver(post_save, sender=User) +@receiver(post_save, sender=Official) def create_user_profile(sender, instance, created, **kwargs): if created: - Official.objects.create(user=instance) + instance.user.first_name = instance.first_name + instance.user.last_name = instance.last_name + instance.user.email = instance.email + instance.user.save() -@receiver(post_save, sender=User) +@receiver(post_save, sender=Official) def save_user_profile(sender, instance, **kwargs): - instance.official.save() + instance.user.first_name = instance.first_name + instance.user.last_name = instance.last_name + instance.user.email = instance.email + instance.user.save() auditlog.register(Tag) diff --git a/webapp/serializers.py b/webapp/serializers.py index b542d55..7cdee73 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -93,8 +93,16 @@ class FeedSerializer(serializers.ModelSerializer): return feed +class OccupationSerializer(serializers.ModelSerializer): + class Meta: + model = Occupation + fields = ('start_date', 'end_date') + + class ContactsSerializer(serializers.ModelSerializer): + current_roles = OccupationSerializer(many=True, read_only=True) + class Meta: model = Official - fields = ('id', 'first_name', 'last_name', 'phone_number', 'role') + fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'current_roles') depth = 2 From 5a29c8c49d1789767f88fcd9ff877d2d62673866 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 20:43:13 +0300 Subject: [PATCH 04/15] Set contact serializer --- webapp/migrations/0059_auto_20190926_2032.py | 23 ++++++++++++++++++++ webapp/models.py | 4 ++-- webapp/serializers.py | 18 ++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 webapp/migrations/0059_auto_20190926_2032.py diff --git a/webapp/migrations/0059_auto_20190926_2032.py b/webapp/migrations/0059_auto_20190926_2032.py new file mode 100644 index 0000000..a956773 --- /dev/null +++ b/webapp/migrations/0059_auto_20190926_2032.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0058_auto_20190926_2010'), + ] + + operations = [ + migrations.RemoveField( + model_name='occupation', + name='occupation', + ), + migrations.AddField( + model_name='occupation', + name='role', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index c3fd53d..4e5414d 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -192,10 +192,10 @@ class Occupation(models.Model): start_date = models.DateField(_('Start date')) end_date = models.DateField(_('End date')) - occupation = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) + role = models.OneToOneField('Role', on_delete=models.SET_NULL, null=True) def __str__(self): - return '{}: {} - {}'.format(self.occupation.name, self.start_date, self.end_date) + return '{}: {} - {}'.format(self.role.name, self.start_date, self.end_date) class Official(models.Model): diff --git a/webapp/serializers.py b/webapp/serializers.py index 7cdee73..3d4a3e8 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -93,10 +93,26 @@ class FeedSerializer(serializers.ModelSerializer): return feed +class CommitteeSerializer(serializers.ModelSerializer): + class Meta: + model = Committee + fields = ['name'] + + +class RoleSerializer(serializers.ModelSerializer): + committee = CommitteeSerializer(read_only=True) + + class Meta: + model = Role + fields = ('name', 'description', 'committee') + + class OccupationSerializer(serializers.ModelSerializer): + role = RoleSerializer(read_only=True) + class Meta: model = Occupation - fields = ('start_date', 'end_date') + fields = ('role', 'start_date', 'end_date') class ContactsSerializer(serializers.ModelSerializer): From 23563651974d1080cf19698ec68ee3f19bd8164e Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 20:52:11 +0300 Subject: [PATCH 05/15] Reconstruct migrations (squash merge request) --- webapp/migrations/0055_auto_20190926_1850.py | 31 ----------- webapp/migrations/0055_auto_20190926_2048.py | 19 +++++++ webapp/migrations/0056_auto_20190926_1857.py | 51 ----------------- webapp/migrations/0056_auto_20190926_2051.py | 58 ++++++++++++++++++++ webapp/migrations/0057_auto_20190926_1915.py | 18 ------ webapp/migrations/0058_auto_20190926_2010.py | 31 ----------- webapp/migrations/0059_auto_20190926_2032.py | 23 -------- 7 files changed, 77 insertions(+), 154 deletions(-) delete mode 100644 webapp/migrations/0055_auto_20190926_1850.py create mode 100644 webapp/migrations/0055_auto_20190926_2048.py delete mode 100644 webapp/migrations/0056_auto_20190926_1857.py create mode 100644 webapp/migrations/0056_auto_20190926_2051.py delete mode 100644 webapp/migrations/0057_auto_20190926_1915.py delete mode 100644 webapp/migrations/0058_auto_20190926_2010.py delete mode 100644 webapp/migrations/0059_auto_20190926_2032.py diff --git a/webapp/migrations/0055_auto_20190926_1850.py b/webapp/migrations/0055_auto_20190926_1850.py deleted file mode 100644 index a1fb4ff..0000000 --- a/webapp/migrations/0055_auto_20190926_1850.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 15:50 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('webapp', '0054_auto_20190313_1642'), - ] - - operations = [ - migrations.CreateModel( - name='Occupation', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('start_date', models.DateField(verbose_name='Start date')), - ('end_date', models.DateField(verbose_name='End date')), - ], - options={ - 'verbose_name': 'Occupation', - 'verbose_name_plural': 'Occupations', - }, - ), - migrations.DeleteModel( - name='official' - ) - ] diff --git a/webapp/migrations/0055_auto_20190926_2048.py b/webapp/migrations/0055_auto_20190926_2048.py new file mode 100644 index 0000000..36f40e0 --- /dev/null +++ b/webapp/migrations/0055_auto_20190926_2048.py @@ -0,0 +1,19 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:48 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0054_auto_20190313_1642'), + ] + + operations = [ + migrations.DeleteModel( + name='official' + ) + ] diff --git a/webapp/migrations/0056_auto_20190926_1857.py b/webapp/migrations/0056_auto_20190926_1857.py deleted file mode 100644 index 6f99cba..0000000 --- a/webapp/migrations/0056_auto_20190926_1857.py +++ /dev/null @@ -1,51 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 15:57 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import phonenumber_field.modelfields - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('webapp', '0055_auto_20190926_1850'), - ] - - operations = [ - migrations.CreateModel( - name='Official', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, verbose_name='Phone number')), - ], - options={ - 'verbose_name': 'Official', - 'verbose_name_plural': 'Officials', - }, - ), - migrations.RemoveField( - model_name='role', - name='end_date', - ), - migrations.RemoveField( - model_name='role', - name='start_date', - ), - migrations.AddField( - model_name='occupation', - name='occupation', - field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), - ), - migrations.AddField( - model_name='official', - name='role_history', - field=models.ManyToManyField(to='webapp.Occupation'), - ), - migrations.AddField( - model_name='official', - name='user', - field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/webapp/migrations/0056_auto_20190926_2051.py b/webapp/migrations/0056_auto_20190926_2051.py new file mode 100644 index 0000000..3c9dbff --- /dev/null +++ b/webapp/migrations/0056_auto_20190926_2051.py @@ -0,0 +1,58 @@ +# Generated by Django 2.1.5 on 2019-09-26 17:51 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import phonenumber_field.modelfields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('webapp', '0055_auto_20190926_2048'), + ] + + operations = [ + migrations.CreateModel( + name='Occupation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_date', models.DateField(verbose_name='Start date')), + ('end_date', models.DateField(verbose_name='End date')), + ], + options={ + 'verbose_name': 'Occupation', + 'verbose_name_plural': 'Occupations', + }, + ), + migrations.CreateModel( + name='Official', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=30, verbose_name='First name')), + ('last_name', models.CharField(max_length=150, verbose_name='Last name')), + ('email', models.EmailField(max_length=254, verbose_name='Email address')), + ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, verbose_name='Phone number')), + ('role_history', models.ManyToManyField(blank=True, to='webapp.Occupation')), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'Official', + 'verbose_name_plural': 'Officials', + }, + ), + migrations.RemoveField( + model_name='role', + name='end_date', + ), + migrations.RemoveField( + model_name='role', + name='start_date', + ), + migrations.AddField( + model_name='occupation', + name='role', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + ] diff --git a/webapp/migrations/0057_auto_20190926_1915.py b/webapp/migrations/0057_auto_20190926_1915.py deleted file mode 100644 index ae2c01f..0000000 --- a/webapp/migrations/0057_auto_20190926_1915.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 16:15 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0056_auto_20190926_1857'), - ] - - operations = [ - migrations.AlterField( - model_name='official', - name='role_history', - field=models.ManyToManyField(blank=True, to='webapp.Occupation'), - ), - ] diff --git a/webapp/migrations/0058_auto_20190926_2010.py b/webapp/migrations/0058_auto_20190926_2010.py deleted file mode 100644 index e7230cd..0000000 --- a/webapp/migrations/0058_auto_20190926_2010.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 17:10 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0057_auto_20190926_1915'), - ] - - operations = [ - migrations.AddField( - model_name='official', - name='email', - field=models.EmailField(default='asd@asd.fi', max_length=254, verbose_name='Email address'), - preserve_default=False, - ), - migrations.AddField( - model_name='official', - name='first_name', - field=models.CharField(default='asd', max_length=30, verbose_name='First name'), - preserve_default=False, - ), - migrations.AddField( - model_name='official', - name='last_name', - field=models.CharField(default='asd', max_length=150, verbose_name='Last name'), - preserve_default=False, - ), - ] diff --git a/webapp/migrations/0059_auto_20190926_2032.py b/webapp/migrations/0059_auto_20190926_2032.py deleted file mode 100644 index a956773..0000000 --- a/webapp/migrations/0059_auto_20190926_2032.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 2.1.5 on 2019-09-26 17:32 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('webapp', '0058_auto_20190926_2010'), - ] - - operations = [ - migrations.RemoveField( - model_name='occupation', - name='occupation', - ), - migrations.AddField( - model_name='occupation', - name='role', - field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), - ), - ] From fef74dd99556d4f2c7e4ad8b6c9856f4b4131785 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 26 Sep 2019 21:03:26 +0300 Subject: [PATCH 06/15] Fix brainfart --- webapp/migrations/0057_auto_20190926_2102.py | 19 +++++++++++++++++++ webapp/models.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 webapp/migrations/0057_auto_20190926_2102.py diff --git a/webapp/migrations/0057_auto_20190926_2102.py b/webapp/migrations/0057_auto_20190926_2102.py new file mode 100644 index 0000000..1317349 --- /dev/null +++ b/webapp/migrations/0057_auto_20190926_2102.py @@ -0,0 +1,19 @@ +# Generated by Django 2.1.5 on 2019-09-26 18:02 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0056_auto_20190926_2051'), + ] + + operations = [ + migrations.AlterField( + model_name='occupation', + name='role', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='webapp.Role'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 4e5414d..2ecad36 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -192,7 +192,7 @@ class Occupation(models.Model): start_date = models.DateField(_('Start date')) end_date = models.DateField(_('End date')) - role = models.OneToOneField('Role', on_delete=models.SET_NULL, null=True) + role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) def __str__(self): return '{}: {} - {}'.format(self.role.name, self.start_date, self.end_date) From 0da0a02bacc52708afbe5801261feec13520117b Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 28 Sep 2019 17:41:37 +0300 Subject: [PATCH 07/15] Get Officials by year with query param year --- webapp/models.py | 15 +++++++++++---- webapp/serializers.py | 4 ++-- webapp/views.py | 6 ++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/webapp/models.py b/webapp/models.py index 2ecad36..875c855 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -194,6 +194,12 @@ class Occupation(models.Model): end_date = models.DateField(_('End date')) role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) + @staticmethod + def occupations_by_year(year): + return Occupation.objects.filter( + end_date__gte=timezone.datetime(year, 1, 1)).filter( + start_date__lte=timezone.datetime(year, 12, 31)) + def __str__(self): return '{}: {} - {}'.format(self.role.name, self.start_date, self.end_date) @@ -217,11 +223,12 @@ class Official(models.Model): @property def current_roles(self): - return self.role_history.all().filter(end_date__gte=timezone.now()).filter(start_date__lte=timezone.now()) + return self.role_history.all().filter(end_date__gte=timezone.now()) - @property - def roles_of_year(self, year): - return self.role_history.all().filter(end_date__gte=timezone.datetime(year, 1, 1)).filter(start_date__lte=timezone.datetime(year, 12, 31)) + @staticmethod + def official_by_year(year): + return Official.objects.filter( + role_history__in=Occupation.occupations_by_year(year)).distinct() def __str__(self): return '{} {}'.format(self.first_name, self.last_name) diff --git a/webapp/serializers.py b/webapp/serializers.py index 3d4a3e8..bd3ad13 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -116,9 +116,9 @@ class OccupationSerializer(serializers.ModelSerializer): class ContactsSerializer(serializers.ModelSerializer): - current_roles = OccupationSerializer(many=True, read_only=True) + role_history = OccupationSerializer(many=True, read_only=True) class Meta: model = Official - fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'current_roles') + fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'role_history') depth = 2 diff --git a/webapp/views.py b/webapp/views.py index 8eeaf00..1aeab93 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -112,6 +112,12 @@ class ContactsViewSet(viewsets.ReadOnlyModelViewSet): serializer_class = ContactsSerializer permission_classes = [IsAuthenticatedOrReadOnly] + def get_queryset(self): + year = self.request.query_params.get('year') + if not year: + return Official.official_by_year(timezone.now().year) + return Official.official_by_year(int(year)) + class TagsViewSet(viewsets.ReadOnlyModelViewSet): queryset = Tag.objects.all() From b58dbde83c26b3b13d470f811cf31355ba56a9c6 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Sat, 28 Sep 2019 19:52:14 +0300 Subject: [PATCH 08/15] Minor cleanup --- webapp/models.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/webapp/models.py b/webapp/models.py index 875c855..52c141a 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -235,16 +235,7 @@ class Official(models.Model): @receiver(post_save, sender=Official) -def create_user_profile(sender, instance, created, **kwargs): - if created: - instance.user.first_name = instance.first_name - instance.user.last_name = instance.last_name - instance.user.email = instance.email - instance.user.save() - - -@receiver(post_save, sender=Official) -def save_user_profile(sender, instance, **kwargs): +def save_user_official(sender, instance, **kwargs): instance.user.first_name = instance.first_name instance.user.last_name = instance.last_name instance.user.email = instance.email From d7f57c5b3a5eb5c17149b11618dff5a92aa96f3a Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 18:02:06 +0300 Subject: [PATCH 09/15] Clean webapp urls --- webapp/urls.py | 54 +------------------------------------------------- 1 file changed, 1 insertion(+), 53 deletions(-) diff --git a/webapp/urls.py b/webapp/urls.py index f3bfa44..353b0ad 100644 --- a/webapp/urls.py +++ b/webapp/urls.py @@ -3,22 +3,8 @@ from django.conf.urls import url, include from rest_framework import routers from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token - -# from rest_framework.urlpatterns import format_suffix_patterns -# from django.conf import settings -# from django.utils.translation import ugettext_lazy as _ - -# from webapp.views import main_index -# from webapp.views import login_view -# from webapp.views import logout_view from webapp.views import about_view -# from webapp.views import guild_view -# from webapp.views import freshmen_view -# from webapp.views import jobs_view -# from webapp.views import event_calendar_view -# from webapp.views import international_view -# from webapp.views import sosso_view -# from webapp.views import contact_view + from webapp.views import EventViewSet, SignupFormViewSet, SignupViewSet,\ FeedViewSet, ContactsViewSet, SavedQuestionsViewSet, RootView, TagsViewSet @@ -41,44 +27,6 @@ urlpatterns = [ url(r'^api/', include(router.urls)), url(r'^api/api-token-auth/', obtain_jwt_token), url(r'^api/api-token-verify/', verify_jwt_token), - - # login stuff - # url(r'^login$', login_view), - # url(r'^logout$', logout_view), - # git revision url(r'^about', about_view), ] -# urlpatterns = [ -# # main -# url(r'^$', main_index), -# url(r'^api/events/$', EventList.as_view(), name='event-list'), -# url(r'^api/events/(?P[0-9]+)/$', EventDetail.as_view(), name='event-detail'), -# url(r'^api/signup/$', SignupFormList.as_view(), name='signupform-list'), -# url(r'^api/signup/(?P[0-9]+)/$', SignupFormDetail.as_view(), name='signup-detail'), - -# url(r'^api/signup/create$', SignupFormCreate.as_view(), name='signupform-create'), - -# # url(r'^signupform/$', SignupFormList.as_view(), name='signupform-list'), -# # url(r'^signupform/(?P[0-9]+)/$', SignupFormDetail.as_view(), name='signupform-detail'), - -# # login stuff -# url(r'^login$', login_view), -# url(r'^logout$', logout_view), - -# # pages -# url(r'^guild', guild_view), -# url(r'^freshmen', freshmen_view), -# url(r'^event_calendar', event_calendar_view), -# url(r'^international', international_view), -# url(r'^sosso', sosso_view), -# url(r'^contact', contact_view), - -# # corporate -# url(r'^jobs', jobs_view), -# ] - - -# if settings.DEBUG: -# from django.contrib.staticfiles.urls import staticfiles_urlpatterns -# urlpatterns += staticfiles_urlpatterns() From e5cc62bbbf096d31ee65a39aa49daabdf4cf65d9 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 18:37:15 +0300 Subject: [PATCH 10/15] Use OccupationSerializer for the Contacts API --- webapp/migrations/0058_auto_20191010_1837.py | 18 ++++++++++++++++++ webapp/models.py | 10 +++------- webapp/serializers.py | 19 +++++++++---------- webapp/views.py | 8 ++++---- 4 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 webapp/migrations/0058_auto_20191010_1837.py diff --git a/webapp/migrations/0058_auto_20191010_1837.py b/webapp/migrations/0058_auto_20191010_1837.py new file mode 100644 index 0000000..7df01b1 --- /dev/null +++ b/webapp/migrations/0058_auto_20191010_1837.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.5 on 2019-10-10 15:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0057_auto_20190926_2102'), + ] + + operations = [ + migrations.AlterField( + model_name='official', + name='role_history', + field=models.ManyToManyField(blank=True, related_name='officials', to='webapp.Occupation'), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 52c141a..4c8d331 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -195,7 +195,7 @@ class Occupation(models.Model): role = models.ForeignKey('Role', on_delete=models.SET_NULL, null=True) @staticmethod - def occupations_by_year(year): + def by_year(year): return Occupation.objects.filter( end_date__gte=timezone.datetime(year, 1, 1)).filter( start_date__lte=timezone.datetime(year, 12, 31)) @@ -219,14 +219,10 @@ class Official(models.Model): last_name = models.CharField(_('Last name'), max_length=150) email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) - role_history = models.ManyToManyField('Occupation', blank=True) - - @property - def current_roles(self): - return self.role_history.all().filter(end_date__gte=timezone.now()) + role_history = models.ManyToManyField('Occupation', 'officials', blank=True) @staticmethod - def official_by_year(year): + def by_year(year): return Official.objects.filter( role_history__in=Occupation.occupations_by_year(year)).distinct() diff --git a/webapp/serializers.py b/webapp/serializers.py index bd3ad13..03f8f1f 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -107,18 +107,17 @@ class RoleSerializer(serializers.ModelSerializer): fields = ('name', 'description', 'committee') +class ContactsSerializer(serializers.ModelSerializer): + class Meta: + model = Official + fields = ('first_name', 'last_name', 'email', 'phone_number') + depth = 2 + + class OccupationSerializer(serializers.ModelSerializer): role = RoleSerializer(read_only=True) + officials = ContactsSerializer(many=True, read_only=True) class Meta: model = Occupation - fields = ('role', 'start_date', 'end_date') - - -class ContactsSerializer(serializers.ModelSerializer): - role_history = OccupationSerializer(many=True, read_only=True) - - class Meta: - model = Official - fields = ('id', 'first_name', 'last_name', 'email', 'phone_number', 'role_history') - depth = 2 + fields = ('role', 'start_date', 'end_date', 'officials') diff --git a/webapp/views.py b/webapp/views.py index 1aeab93..e024e4c 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -108,15 +108,15 @@ class FeedViewSet(viewsets.ModelViewSet): class ContactsViewSet(viewsets.ReadOnlyModelViewSet): - queryset = Official.objects.all() - serializer_class = ContactsSerializer + queryset = Occupation.objects.all() + serializer_class = OccupationSerializer permission_classes = [IsAuthenticatedOrReadOnly] def get_queryset(self): year = self.request.query_params.get('year') if not year: - return Official.official_by_year(timezone.now().year) - return Official.official_by_year(int(year)) + return Occupation.by_year(timezone.now().year) + return Occupation.by_year(int(year)) class TagsViewSet(viewsets.ReadOnlyModelViewSet): From 86af724cccfd67e105fb18a0d6f9da45f2fe4e47 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 19:03:26 +0300 Subject: [PATCH 11/15] Add translations to API --- webapp/admin.py | 2 +- webapp/migrations/0059_auto_20191010_1900.py | 23 ++++++++++++++++++++ webapp/serializers.py | 4 ++-- webapp/translation.py | 10 +++++++-- 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 webapp/migrations/0059_auto_20191010_1900.py diff --git a/webapp/admin.py b/webapp/admin.py index dd0c36f..04d51cf 100644 --- a/webapp/admin.py +++ b/webapp/admin.py @@ -16,7 +16,7 @@ admin.site.register(Event, TranslationAdmin) admin.site.register(SignupForm, TranslationAdmin) admin.site.register(Signup, TranslationAdmin) admin.site.register(TemplateQuestion, TranslationAdmin) +admin.site.register(Committee, TranslationAdmin) admin.site.register(Official) admin.site.register(Occupation) admin.site.register(Role) -admin.site.register(Committee) diff --git a/webapp/migrations/0059_auto_20191010_1900.py b/webapp/migrations/0059_auto_20191010_1900.py new file mode 100644 index 0000000..8fc9972 --- /dev/null +++ b/webapp/migrations/0059_auto_20191010_1900.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.5 on 2019-10-10 16:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0058_auto_20191010_1837'), + ] + + operations = [ + migrations.AddField( + model_name='committee', + name='name_en', + field=models.CharField(max_length=255, null=True, verbose_name='Name'), + ), + migrations.AddField( + model_name='committee', + name='name_fi', + field=models.CharField(max_length=255, null=True, verbose_name='Name'), + ), + ] diff --git a/webapp/serializers.py b/webapp/serializers.py index 03f8f1f..b4db898 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -96,7 +96,7 @@ class FeedSerializer(serializers.ModelSerializer): class CommitteeSerializer(serializers.ModelSerializer): class Meta: model = Committee - fields = ['name'] + fields = ['name_fi', 'name_en'] class RoleSerializer(serializers.ModelSerializer): @@ -104,7 +104,7 @@ class RoleSerializer(serializers.ModelSerializer): class Meta: model = Role - fields = ('name', 'description', 'committee') + fields = ('name_fi', 'name_en', 'description_fi', 'description_en', 'committee') class ContactsSerializer(serializers.ModelSerializer): diff --git a/webapp/translation.py b/webapp/translation.py index 73713ca..24c4b62 100644 --- a/webapp/translation.py +++ b/webapp/translation.py @@ -1,8 +1,7 @@ """Translation classes.""" from modeltranslation.translator import register, TranslationOptions -from webapp.models import BaseFeed, Feed, Tag, Event, Signup, SignupForm, TemplateQuestion -from webapp.models import PresetRole, BaseRole +from webapp.models import * @register(BaseFeed) @@ -66,3 +65,10 @@ class PresetRoleTranslationOptions(TranslationOptions): """Class for PresetRole translation options.""" fields = ('description',) + + +@register(Committee) +class CommitteeTranslationOptions(TranslationOptions): + """Class for PresetRole translation options.""" + + fields = ('name',) From 59dcb382ceb23848cf483747a63b3ceb889d6b55 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 19:06:48 +0300 Subject: [PATCH 12/15] Add images to Officials --- webapp/migrations/0060_official_image.py | 18 ++++++++++++++++++ webapp/models.py | 1 + webapp/serializers.py | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 webapp/migrations/0060_official_image.py diff --git a/webapp/migrations/0060_official_image.py b/webapp/migrations/0060_official_image.py new file mode 100644 index 0000000..0df934f --- /dev/null +++ b/webapp/migrations/0060_official_image.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.5 on 2019-10-10 16:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('webapp', '0059_auto_20191010_1900'), + ] + + operations = [ + migrations.AddField( + model_name='official', + name='image', + field=models.ImageField(null=True, upload_to=''), + ), + ] diff --git a/webapp/models.py b/webapp/models.py index 4c8d331..7676bf3 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -220,6 +220,7 @@ class Official(models.Model): email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) role_history = models.ManyToManyField('Occupation', 'officials', blank=True) + image = models.ImageField(null=True) @staticmethod def by_year(year): diff --git a/webapp/serializers.py b/webapp/serializers.py index b4db898..ae0b69e 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -110,7 +110,7 @@ class RoleSerializer(serializers.ModelSerializer): class ContactsSerializer(serializers.ModelSerializer): class Meta: model = Official - fields = ('first_name', 'last_name', 'email', 'phone_number') + fields = ('first_name', 'last_name', 'email', 'phone_number', 'image') depth = 2 From 971247e67c61f0f34037468002038e9e72311bc7 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 19:10:35 +0300 Subject: [PATCH 13/15] Show board status --- webapp/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/serializers.py b/webapp/serializers.py index ae0b69e..9ea9456 100644 --- a/webapp/serializers.py +++ b/webapp/serializers.py @@ -104,7 +104,7 @@ class RoleSerializer(serializers.ModelSerializer): class Meta: model = Role - fields = ('name_fi', 'name_en', 'description_fi', 'description_en', 'committee') + fields = ('name_fi', 'name_en', 'description_fi', 'description_en', 'committee', 'is_board') class ContactsSerializer(serializers.ModelSerializer): From 09e973fab1198fdeb4885974cd379cbf601149c2 Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 20:48:27 +0300 Subject: [PATCH 14/15] Allow missing official image --- webapp/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/models.py b/webapp/models.py index 7676bf3..520af45 100644 --- a/webapp/models.py +++ b/webapp/models.py @@ -220,7 +220,7 @@ class Official(models.Model): email = models.EmailField(_('Email address')) phone_number = PhoneNumberField(_('Phone number')) role_history = models.ManyToManyField('Occupation', 'officials', blank=True) - image = models.ImageField(null=True) + image = models.ImageField(blank=True, null=True) @staticmethod def by_year(year): From c408a6532e5376541d605f9c3e8af1c77900e52f Mon Sep 17 00:00:00 2001 From: Aarni Halinen Date: Thu, 10 Oct 2019 20:48:39 +0300 Subject: [PATCH 15/15] Add committee API --- webapp/urls.py | 4 ++-- webapp/views.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/webapp/urls.py b/webapp/urls.py index 353b0ad..535a13d 100644 --- a/webapp/urls.py +++ b/webapp/urls.py @@ -6,8 +6,7 @@ from rest_framework_jwt.views import obtain_jwt_token, verify_jwt_token from webapp.views import about_view -from webapp.views import EventViewSet, SignupFormViewSet, SignupViewSet,\ - FeedViewSet, ContactsViewSet, SavedQuestionsViewSet, RootView, TagsViewSet +from webapp.views import * class APIRouter(routers.DefaultRouter): @@ -20,6 +19,7 @@ router.register(r'signupForm', SignupFormViewSet) router.register(r'signup', SignupViewSet) router.register(r'feed', FeedViewSet) router.register(r'contacts', ContactsViewSet) +router.register(r'committees', CommitteeViewSet) router.register(r'questions', SavedQuestionsViewSet) router.register(r'tags', TagsViewSet) diff --git a/webapp/views.py b/webapp/views.py index e024e4c..2faef8c 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -119,6 +119,12 @@ class ContactsViewSet(viewsets.ReadOnlyModelViewSet): return Occupation.by_year(int(year)) +class CommitteeViewSet(viewsets.ReadOnlyModelViewSet): + queryset = Committee.objects.all() + serializer_class = CommitteeSerializer + permission_classes = [IsAuthenticatedOrReadOnly] + + class TagsViewSet(viewsets.ReadOnlyModelViewSet): queryset = Tag.objects.all() serializer_class = TagSerializer