From 85efb836af2921f55e9c27adced86db61697697d Mon Sep 17 00:00:00 2001 From: Guillaume Pellerin Date: Fri, 21 Oct 2016 19:37:31 +0200 Subject: [PATCH] Add M2M fields to activities, fix team page order --- app/organization/core/models.py | 17 ++++ app/organization/network/admin.py | 4 +- .../commands/import-ircam-person-xls.py | 11 +++ .../migrations/0043_auto_20161021_1507.py | 36 ++++++++ .../migrations/0044_auto_20161021_1553.py | 26 ++++++ .../migrations/0045_auto_20161021_1803.py | 87 +++++++++++++++++++ app/organization/network/models.py | 35 +++----- app/templates/agenda/event_detail.html | 2 - .../magazine/article/article_detail.html | 2 - app/templates/pages/custompage.html | 2 - app/templates/pages/departmentpage.html | 2 - app/templates/pages/page.html | 9 +- app/templates/pages/teampage.html | 39 +++++---- 13 files changed, 219 insertions(+), 53 deletions(-) create mode 100644 app/organization/network/migrations/0043_auto_20161021_1507.py create mode 100644 app/organization/network/migrations/0044_auto_20161021_1553.py create mode 100644 app/organization/network/migrations/0045_auto_20161021_1803.py diff --git a/app/organization/core/models.py b/app/organization/core/models.py index d8546e02..0277e5d7 100644 --- a/app/organization/core/models.py +++ b/app/organization/core/models.py @@ -9,6 +9,8 @@ from mezzanine.pages.models import Page, RichText from mezzanine.core.fields import RichTextField, OrderField, FileField from mezzanine.core.models import Displayable, Slugged, Orderable +from django_countries.fields import CountryField + COLOR_CHOICES = (('black', _('black')), ('yellow', _('yellow')), ('red', _('red'))) ALIGNMENT_CHOICES = (('left', _('left')), ('center', _('center')), ('right', _('right'))) @@ -236,3 +238,18 @@ class Dated(models.Model): class Meta: abstract = True + + +class Address(models.Model): + """(Address description)""" + + address = models.TextField(_('address'), blank=True) + postal_code = models.CharField(_('postal code'), max_length=16, null=True, blank=True) + city = models.CharField(_('city'), max_length=255, null=True, blank=True) + country = CountryField(_('country'), null=True, blank=True) + + def __str__(self): + return ' '.join((self.address, self.postal_code)) + + class Meta: + abstract = True diff --git a/app/organization/network/admin.py b/app/organization/network/admin.py index 4a04fc19..d2ce9d4e 100644 --- a/app/organization/network/admin.py +++ b/app/organization/network/admin.py @@ -111,7 +111,9 @@ class PersonAdmin(BaseTranslationOrderedModelAdmin): first_fields = ['last_name', 'first_name', 'title', 'gender', 'user'] search_fields = ['last_name', 'first_name'] list_display = ['last_name', 'first_name', 'description', 'email', 'gender'] - list_filter = ['person_title', 'activities__date_from', 'activities__date_to', 'activities__is_permanent', 'activities__framework', 'activities__grade', 'activities__function', 'activities__team', 'activities__project',] + list_filter = ['person_title', 'activities__date_from', 'activities__date_to', + 'activities__is_permanent', 'activities__framework', 'activities__grade', + 'activities__function', 'activities__team',] class PersonActivityAdmin(admin.ModelAdmin): diff --git a/app/organization/network/management/commands/import-ircam-person-xls.py b/app/organization/network/management/commands/import-ircam-person-xls.py index c1a9c2e3..3efe10fc 100644 --- a/app/organization/network/management/commands/import-ircam-person-xls.py +++ b/app/organization/network/management/commands/import-ircam-person-xls.py @@ -64,6 +64,7 @@ class IrcamXLS: class IrcamPerson(object): organization = Organization.objects.get(name='Ircam') + spliters = ['/', ','] def __init__(self, row, datemode): self.row = row @@ -94,6 +95,16 @@ class IrcamPerson(object): def get_or_create_name(self, model, column_id): return model.objects.get_or_create(name=self.row[column_id].value)[0] if self.row[column_id].value else None + def split_names(self, names): + name_list = [] + for spliter in self.spliters: + if spliter in names: + name_list = names.split(spliter) + if name_list: + for map(str.strip, name_list) + return name_list + return names + def get_person(self, value): if value: name_exceptions = ['de', 'von'] diff --git a/app/organization/network/migrations/0043_auto_20161021_1507.py b/app/organization/network/migrations/0043_auto_20161021_1507.py new file mode 100644 index 00000000..d426f0de --- /dev/null +++ b/app/organization/network/migrations/0043_auto_20161021_1507.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-21 13:07 +from __future__ import unicode_literals + +from django.db import migrations, models +import django_countries.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0042_auto_20161021_1319'), + ] + + operations = [ + migrations.AlterField( + model_name='organization', + name='address', + field=models.TextField(blank=True, verbose_name='address'), + ), + migrations.AlterField( + model_name='organization', + name='city', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='city'), + ), + migrations.AlterField( + model_name='organization', + name='country', + field=django_countries.fields.CountryField(blank=True, max_length=2, null=True, verbose_name='country'), + ), + migrations.AlterField( + model_name='organization', + name='postal_code', + field=models.CharField(blank=True, max_length=16, null=True, verbose_name='postal code'), + ), + ] diff --git a/app/organization/network/migrations/0044_auto_20161021_1553.py b/app/organization/network/migrations/0044_auto_20161021_1553.py new file mode 100644 index 00000000..6edd4bef --- /dev/null +++ b/app/organization/network/migrations/0044_auto_20161021_1553.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-21 13:53 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0043_auto_20161021_1507'), + ] + + operations = [ + migrations.AddField( + model_name='personactivity', + name='phd_officer_3', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='phd_officer_3_activity', to='organization-network.Person', verbose_name='PhD officer 3'), + ), + migrations.AddField( + model_name='personactivity', + name='third_employer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='third_employer_activity', to='organization-network.Organization', verbose_name='third employer'), + ), + ] diff --git a/app/organization/network/migrations/0045_auto_20161021_1803.py b/app/organization/network/migrations/0045_auto_20161021_1803.py new file mode 100644 index 00000000..ea1d2adc --- /dev/null +++ b/app/organization/network/migrations/0045_auto_20161021_1803.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-10-21 16:03 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-projects', '0022_projectlink_title'), + ('organization-network', '0044_auto_20161021_1553'), + ] + + operations = [ + migrations.RemoveField( + model_name='personactivity', + name='phd_director', + ), + migrations.RemoveField( + model_name='personactivity', + name='phd_officer_1', + ), + migrations.RemoveField( + model_name='personactivity', + name='phd_officer_2', + ), + migrations.RemoveField( + model_name='personactivity', + name='phd_officer_3', + ), + migrations.RemoveField( + model_name='personactivity', + name='project', + ), + migrations.AddField( + model_name='organization', + name='initials', + field=models.CharField(blank=True, max_length=128, null=True, verbose_name='initials'), + ), + migrations.AddField( + model_name='personactivity', + name='phd_directors', + field=models.ManyToManyField(blank=True, related_name='phd_director_activities', to='organization-network.Person', verbose_name='PhD directors'), + ), + migrations.AddField( + model_name='personactivity', + name='phd_officers', + field=models.ManyToManyField(blank=True, related_name='phd_officer_activities', to='organization-network.Person', verbose_name='PhD officers'), + ), + migrations.AddField( + model_name='personactivity', + name='projects', + field=models.ManyToManyField(blank=True, related_name='activities', to='organization-projects.Project', verbose_name='projects'), + ), + migrations.AlterField( + model_name='personactivity', + name='attachment_organization', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='attachment_activities', to='organization-network.Organization', verbose_name='attachment organization'), + ), + migrations.AlterField( + model_name='personactivity', + name='employer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='employer_activities', to='organization-network.Organization', verbose_name='employer'), + ), + migrations.AlterField( + model_name='personactivity', + name='second_employer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='second_employer_activities', to='organization-network.Organization', verbose_name='second employer'), + ), + migrations.AlterField( + model_name='personactivity', + name='second_team', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='second_team_activities', to='organization-network.Team', verbose_name='second team'), + ), + migrations.AlterField( + model_name='personactivity', + name='team', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_activities', to='organization-network.Team', verbose_name='team'), + ), + migrations.AlterField( + model_name='personactivity', + name='third_employer', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='third_employer_activities', to='organization-network.Organization', verbose_name='third employer'), + ), + ] diff --git a/app/organization/network/models.py b/app/organization/network/models.py index bdf73c91..490a7416 100644 --- a/app/organization/network/models.py +++ b/app/organization/network/models.py @@ -28,7 +28,6 @@ from organization.core.models import * from organization.media.models import * from organization.pages.models import CustomPage -from django_countries.fields import CountryField # from .nationalities.fields import NationalityField # Hack to have these strings translated @@ -61,21 +60,6 @@ PATTERN_CHOICES = [ ALIGNMENT_CHOICES = (('left', _('left')), ('left', _('left')), ('right', _('right'))) -class Address(models.Model): - """(Address description)""" - - address = models.TextField(_('address')) - postal_code = models.CharField(_('postal code'), max_length=16) - city = models.CharField(_('city'), max_length=255) - country = CountryField(_('country')) - - def __str__(self): - return ' '.join((self.address, self.postal_code)) - - class Meta: - abstract = True - - class Organization(Named, Address, URL, AdminThumbRelatedMixin): """(Organization description)""" @@ -83,6 +67,7 @@ class Organization(Named, Address, URL, AdminThumbRelatedMixin): lat = models.DecimalField(max_digits=10, decimal_places=7, blank=True, null=True, verbose_name="Latitude", help_text="Calculated automatically if mappable location is set.") lon = models.DecimalField(max_digits=10, decimal_places=7, blank=True, null=True, verbose_name="Longitude", help_text="Calculated automatically if mappable location is set.") type = models.ForeignKey('OrganizationType', verbose_name=_('organization type'), blank=True, null=True, on_delete=models.SET_NULL) + initials = models.CharField(_('initials'), max_length=128, blank=True, null=True) is_on_map = models.BooleanField(_('is on map'), default=False) admin_thumb_type = 'logo' @@ -403,24 +388,24 @@ class PersonActivity(Period): grade = models.ForeignKey(ActivityGrade, verbose_name=_('grade'), blank=True, null=True, on_delete=models.SET_NULL) function = models.ForeignKey(ActivityFunction, verbose_name=_('function'), blank=True, null=True, on_delete=models.SET_NULL) - employer = models.ForeignKey(Organization, verbose_name=_('employer'), related_name='employer_activity', blank=True, null=True, on_delete=models.SET_NULL) - attachment_organization = models.ForeignKey(Organization, verbose_name=_('attachment organization'), related_name='attachment_activity', blank=True, null=True, on_delete=models.SET_NULL) - second_employer = models.ForeignKey(Organization, verbose_name=_('second employer'), related_name='second_employer_activity', blank=True, null=True, on_delete=models.SET_NULL) + employer = models.ForeignKey(Organization, verbose_name=_('employer'), related_name='employer_activities', blank=True, null=True, on_delete=models.SET_NULL) + attachment_organization = models.ForeignKey(Organization, verbose_name=_('attachment organization'), related_name='attachment_activities', blank=True, null=True, on_delete=models.SET_NULL) + second_employer = models.ForeignKey(Organization, verbose_name=_('second employer'), related_name='second_employer_activities', blank=True, null=True, on_delete=models.SET_NULL) + third_employer = models.ForeignKey(Organization, verbose_name=_('third employer'), related_name='third_employer_activities', blank=True, null=True, on_delete=models.SET_NULL) umr = models.ForeignKey(UMR, verbose_name=_('UMR'), blank=True, null=True, on_delete=models.SET_NULL) - team = models.ForeignKey('Team', verbose_name=_('team'), related_name='team_activity', blank=True, null=True, on_delete=models.SET_NULL) - second_team = models.ForeignKey('Team', verbose_name=_('second team'), related_name='second_team_activity', blank=True, null=True, on_delete=models.SET_NULL) + team = models.ForeignKey('Team', verbose_name=_('team'), related_name='team_activities', blank=True, null=True, on_delete=models.SET_NULL) + second_team = models.ForeignKey('Team', verbose_name=_('second team'), related_name='second_team_activities', blank=True, null=True, on_delete=models.SET_NULL) second_team_text = models.CharField(_('second team text'), blank=True, null=True, max_length=256) - project = models.ForeignKey('organization-projects.Project', verbose_name=_('project'), blank=True, null=True, on_delete=models.SET_NULL) + projects = models.ManyToManyField('organization-projects.Project', verbose_name=_('projects'), related_name='activities', blank=True) rd_quota_float = models.IntegerField(_('R&D quota (float)'), blank=True, null=True) rd_quota_text = models.CharField(_('R&D quota (text)'), blank=True, null=True, max_length=128) rd_program = models.TextField(_('R&D program'), blank=True) budget_code = models.ForeignKey(BudgetCode, blank=True, null=True, on_delete=models.SET_NULL) phd_doctoral_school = models.ForeignKey(Organization, verbose_name=_('doctoral school'), blank=True, null=True, on_delete=models.SET_NULL) - phd_director = models.ForeignKey('Person', verbose_name=_('PhD director'), related_name='phd_director_activity', blank=True, null=True, on_delete=models.SET_NULL) - phd_officer_1 = models.ForeignKey('Person', verbose_name=_('PhD officer 1'), related_name='phd_officer_1_activity', blank=True, null=True, on_delete=models.SET_NULL) - phd_officer_2 = models.ForeignKey('Person', verbose_name=_('PhD officer 2'), related_name='phd_officer_2_activity', blank=True, null=True, on_delete=models.SET_NULL) + phd_directors = models.ManyToManyField('Person', verbose_name=_('PhD directors'), related_name='phd_director_activities', blank=True) + phd_officers = models.ManyToManyField('Person', verbose_name=_('PhD officers'), related_name='phd_officer_activities', blank=True) phd_defense_date = models.DateField(_('PhD defense date'), blank=True, null=True) phd_title = models.TextField(_('PhD title'), blank=True) phd_postdoctoralsituation = models.CharField(_('post-doctoral situation'), blank=True, max_length=256) diff --git a/app/templates/agenda/event_detail.html b/app/templates/agenda/event_detail.html index 5a5471c2..95c10e05 100644 --- a/app/templates/agenda/event_detail.html +++ b/app/templates/agenda/event_detail.html @@ -59,8 +59,6 @@ {% editable event.content %} {{ event.content|richtext_filters|safe }} {% endeditable %} - {% else %} - {% lorem 3 p %} {% endif %} {% endblock %} {% endblock %} diff --git a/app/templates/magazine/article/article_detail.html b/app/templates/magazine/article/article_detail.html index 8fa7a1d0..826203cf 100644 --- a/app/templates/magazine/article/article_detail.html +++ b/app/templates/magazine/article/article_detail.html @@ -62,8 +62,6 @@ {% editable article.content %} {{ article.content|richtext_filters|safe }} {% endeditable %} - {% else %} - {% lorem 3 p %} {% endif %} {% endblock %} diff --git a/app/templates/pages/custompage.html b/app/templates/pages/custompage.html index 27967806..60d781f7 100644 --- a/app/templates/pages/custompage.html +++ b/app/templates/pages/custompage.html @@ -33,8 +33,6 @@ {% editable page.custompage.content %} {{ page.custompage.content|richtext_filters|safe }} {% endeditable %} - {% else %} - {% lorem 3 p %} {% endif %} {% if page.get_ascendants|length == 1 %} diff --git a/app/templates/pages/departmentpage.html b/app/templates/pages/departmentpage.html index 0fd73d02..277f0b6c 100644 --- a/app/templates/pages/departmentpage.html +++ b/app/templates/pages/departmentpage.html @@ -30,8 +30,6 @@ {% editable page.departmentpage.content %} {{ page.departmentpage.content|richtext_filters|safe }} {% endeditable %} - {% else %} - {% lorem 3 p %} {% endif %} {% endblock %} diff --git a/app/templates/pages/page.html b/app/templates/pages/page.html index b5b04dee..1ec18301 100644 --- a/app/templates/pages/page.html +++ b/app/templates/pages/page.html @@ -108,20 +108,25 @@ {% block page_person_list %} {% endblock %} + {% block page_sub_content %} {% with object.blocks.all as blocks %} {% include "core/inc/block.html" %} {% endwith %} {% endblock %} + {% block related_project %} {% endblock %} + + {% block products %} + {% endblock %} + {% block logo %} {% endblock %}
- {% block products %} - {% endblock %} + {% block page_related_content %} {% with page.dynamic_content_pages.all as dynamic_content %} {% include "core/inc/related_content.html" %} diff --git a/app/templates/pages/teampage.html b/app/templates/pages/teampage.html index f047bfb4..04903230 100644 --- a/app/templates/pages/teampage.html +++ b/app/templates/pages/teampage.html @@ -33,8 +33,6 @@ {% editable page.teampage.content %} {{ page.teampage.content|richtext_filters|safe }} {% endeditable %} - {% else %} - {% lorem 3 p %} {% endif %} {% if page.get_ascendants|length == 1 %} @@ -79,9 +77,9 @@ {% endblock %} {% block page_sub_content %} - {% with page.teampage.blocks.all as blocks %} - {% include "core/inc/block.html" %} - {% endwith %} + {% with object.blocks.all|slice:'1' as blocks %} + {% include "core/inc/block.html" %} + {% endwith %} {% endblock %} {% block related_project %} @@ -109,22 +107,29 @@
- - {% if page.teampage.product_lists.all %} -

{% trans "Products" %}

- {% for page_product_list in page.teampage.product_lists.all %} - {% with page_product_list.list as list %} - {% with "shop/includes/product_list_"|add:list.style|add:"_style.html" as template %} - {% include template %} - {% endwith %} - {% endwith %} - {% endfor %} - {% endif %} - {% endif %} {% endblock %} +{% block page_sub_content_2 %} + {% with object.blocks.all|slice:'2:' as blocks %} + {% include "core/inc/block.html" %} + {% endwith %} +{% endblock %} + +{% block products %} +{% if page.teampage.product_lists.all %} +

{% trans "Products" %}

+ {% for page_product_list in page.teampage.product_lists.all %} + {% with page_product_list.list as list %} + {% with "shop/includes/product_list_"|add:list.style|add:"_style.html" as template %} + {% include template %} + {% endwith %} + {% endwith %} + {% endfor %} +{% endif %} +{% endblock %} + {% block logo %} {% with page.teampage.images.all|get_type:'logo' as images %} {% if images %} -- 2.39.5