From 1702e884b187817599efd95180c695525cd4064b Mon Sep 17 00:00:00 2001 From: Emilie Date: Thu, 8 Dec 2016 13:05:44 +0100 Subject: [PATCH] [Linked orga logo] : version 2 with auto completion on orga + list orga --- app/local_settings.py | 1 + app/organization/core/context_processors.py | 19 ++++- app/organization/network/admin.py | 33 ++++++- app/organization/network/forms.py | 33 ++++++- .../migrations/0065_auto_20161208_1244.py | 85 +++++++++++++++++++ app/organization/network/models.py | 26 ++++-- app/organization/network/translation.py | 18 ++++ app/organization/network/urls.py | 3 + app/organization/network/views.py | 24 ++++++ .../sass/modules/_linked-organizations.scss | 5 +- .../core/inc/linked_organization_content.html | 16 ---- app/templates/includes/footer.html | 13 +-- app/templates/pages/custompage.html | 2 +- app/templates/pages/departmentpage.html | 3 +- .../includes/linked_organization_content.html | 18 ++++ .../includes}/linked_organization_footer.html | 2 + .../linked_organization_footer_2.html | 8 ++ app/templates/pages/projecttopicpage.html | 2 +- app/templates/pages/teampage.html | 2 +- app/templates/projects/project_detail.html | 2 +- 20 files changed, 268 insertions(+), 47 deletions(-) create mode 100644 app/organization/network/migrations/0065_auto_20161208_1244.py delete mode 100644 app/templates/core/inc/linked_organization_content.html create mode 100644 app/templates/pages/page/includes/linked_organization_content.html rename app/templates/{core/inc => pages/page/includes}/linked_organization_footer.html (89%) create mode 100644 app/templates/pages/page/includes/linked_organization_footer_2.html diff --git a/app/local_settings.py b/app/local_settings.py index 0fe59bd7..4e71f238 100644 --- a/app/local_settings.py +++ b/app/local_settings.py @@ -103,6 +103,7 @@ ADMIN_MENU_ORDER = ( (_('Magazine'), ('organization-magazine.Article', 'organization-magazine.Brief',)), (_('Network'), ('organization-network.Organization', + 'organization-network.OrganizationLinked', 'organization-network.Department', 'organization-network.Team', 'organization-network.Person', diff --git a/app/organization/core/context_processors.py b/app/organization/core/context_processors.py index be0e0ebc..6eeda035 100644 --- a/app/organization/core/context_processors.py +++ b/app/organization/core/context_processors.py @@ -1,7 +1,7 @@ from django.conf import settings # import the settings file from datetime import datetime, date from organization.pages.models import Page -from organization.network.models import Organization +from organization.network.models import Organization, OrganizationLinkedInline def settings(request): date_now = datetime.now() @@ -15,10 +15,20 @@ def settings(request): if newsletter_page: newsletter_subscribing_url = newsletter_page.first().get_absolute_url() - # HOST ORGANIZATION + # HOST ORGANIZATIONS host_org = Organization.objects.get(is_host=True) - linked_org_content = host_org.organizations_content.filter(organizations_content__id=host_org.id).order_by('order') - linked_org_footer = host_org.organizations_footer.filter(organizations_footer__id=host_org.id).order_by('order') + organization_lists = [] + + for orga_linked_block in host_org.organization_linked_block.all(): + organizations = [] + for orga_list in OrganizationLinkedInline.objects.filter(organization_list_id=orga_linked_block.organization_linked_id): + organizations.append(orga_list.organization) + organization_lists.append(organizations) + + linked_org_content = organization_lists[0] if len(organization_lists) > 0 else None + linked_org_footer = organization_lists[1] if len(organization_lists) > 1 else None + linked_org_footer_2 = organization_lists[2] if len(organization_lists) > 2 else None + research_slug = "recherche" return {'current_season': current_season, @@ -27,5 +37,6 @@ def settings(request): 'host_organization': host_org, 'linked_organization_content' : linked_org_content, 'linked_organization_footer' : linked_org_footer, + 'linked_organization_footer_2' : linked_org_footer_2, 'research_slug' : research_slug } diff --git a/app/organization/network/admin.py b/app/organization/network/admin.py index caa0bc7e..dd6770b1 100644 --- a/app/organization/network/admin.py +++ b/app/organization/network/admin.py @@ -13,6 +13,29 @@ from organization.pages.admin import PageImageInline, PageBlockInline, PagePlayl from organization.shop.models import PageProductList +class OrganizationAdminInline(StackedDynamicInlineAdmin): + + model = OrganizationLinkedInline + form = OrganizationLinkedForm + + +class OrganizationLinkedAdmin(BaseTranslationOrderedModelAdmin): + + inlines = (OrganizationAdminInline,) + first_fields = ['name',] + + class Media: + js = ( + static("mezzanine/js/admin/dynamic_inline.js"), + ) + + +class OrganizationLinkedBlockInlineAdmin(StackedDynamicInlineAdmin): + + model = OrganizationLinkedBlockInline + form = OrganizationLinkedListForm + + class OrganizationPlaylistInline(TabularDynamicInlineAdmin): model = OrganizationPlaylist @@ -33,17 +56,20 @@ class OrganizationBlockInline(StackedDynamicInlineAdmin): model = OrganizationBlock -class OrganizationAdmin(BaseTranslationModelAdmin): +class OrganizationAdmin(BaseTranslationOrderedModelAdmin): model = Organization inlines = [ OrganizationPlaylistInline, OrganizationImageInline, OrganizationBlockInline, - OrganizationLinkInline ] - filter_horizontal = ['organizations_content', 'organizations_footer'] + OrganizationLinkInline, + OrganizationLinkedBlockInlineAdmin + ] list_display = ['name', 'type', 'admin_thumb'] list_filter = ['is_on_map',] search_fields = ['name',] + first_fields = ['name',] + class PageProductListInline(TabularDynamicInlineAdmin): @@ -206,6 +232,7 @@ class TrainingTopicAdmin(BaseTranslationModelAdmin): model = TrainingTopic +admin.site.register(OrganizationLinked, OrganizationLinkedAdmin) admin.site.register(Organization, OrganizationAdmin) admin.site.register(OrganizationType) admin.site.register(Department, DepartmentAdmin) diff --git a/app/organization/network/forms.py b/app/organization/network/forms.py index cb860c74..e8774977 100644 --- a/app/organization/network/forms.py +++ b/app/organization/network/forms.py @@ -5,7 +5,14 @@ from django import forms from django.forms.widgets import HiddenInput from django.forms import ModelForm from mezzanine.core.models import Orderable -from organization.network.models import Person, PersonListBlock, PersonListBlockInline, PageCustomPersonListBlockInline +from organization.network.models import (Person, + PersonListBlock, + PersonListBlockInline, + PageCustomPersonListBlockInline, + OrganizationLinked, + OrganizationLinkedInline, + OrganizationLinkedBlockInline, + Organization) from organization.pages.models import Page, CustomPage @@ -31,3 +38,27 @@ class PersonListBlockInlineForm(forms.ModelForm): class Meta: model = PersonListBlockInline fields = ('__all__') + + +class OrganizationLinkedListForm(forms.ModelForm): + + organization_linked = forms.ModelChoiceField( + queryset=OrganizationLinked.objects.all(), + widget=autocomplete.ModelSelect2(url='organization-linked-list-autocomplete') + ) + + class Meta: + model = OrganizationLinkedBlockInline + fields = ('organization_linked',) + + +class OrganizationLinkedForm(forms.ModelForm): + + organization = forms.ModelChoiceField( + queryset=Organization.objects.all(), + widget=autocomplete.ModelSelect2(url='organization-linked-autocomplete') + ) + + class Meta: + model = OrganizationLinkedInline + fields = ('organization',) diff --git a/app/organization/network/migrations/0065_auto_20161208_1244.py b/app/organization/network/migrations/0065_auto_20161208_1244.py new file mode 100644 index 00000000..27204f09 --- /dev/null +++ b/app/organization/network/migrations/0065_auto_20161208_1244.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-12-08 11:44 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion +import mezzanine.core.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-network', '0064_auto_20161205_1536'), + ] + + operations = [ + migrations.CreateModel( + name='OrganizationLinked', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=1024, verbose_name='title')), + ('description', models.TextField(blank=True, verbose_name='description')), + ], + options={ + 'verbose_name': 'Organization Linked', + }, + ), + migrations.CreateModel( + name='OrganizationLinkedBlockInline', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('_order', mezzanine.core.fields.OrderField(null=True, verbose_name='Order')), + ('title', models.CharField(max_length=1024, verbose_name='title')), + ('description', models.TextField(blank=True, verbose_name='description')), + ('organization_linked', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='organization_linked_block_inline_list', to='organization-network.OrganizationLinked', verbose_name='organization list')), + ], + options={ + 'ordering': ('_order',), + }, + ), + migrations.CreateModel( + name='OrganizationLinkedInline', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('_order', mezzanine.core.fields.OrderField(null=True, verbose_name='Order')), + ('title', models.CharField(max_length=1024, verbose_name='title')), + ('description', models.TextField(blank=True, verbose_name='description')), + ], + options={ + 'ordering': ('_order',), + }, + ), + migrations.RemoveField( + model_name='organization', + name='order', + ), + migrations.RemoveField( + model_name='organization', + name='organizations_content', + ), + migrations.RemoveField( + model_name='organization', + name='organizations_footer', + ), + migrations.AddField( + model_name='organization', + name='_order', + field=mezzanine.core.fields.OrderField(null=True, verbose_name='Order'), + ), + migrations.AddField( + model_name='organizationlinkedinline', + name='organization', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='organization_linked_inline_from', to='organization-network.Organization', verbose_name='organization'), + ), + migrations.AddField( + model_name='organizationlinkedinline', + name='organization_list', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='organization_linked_inline_linked', to='organization-network.OrganizationLinked', verbose_name='organization linked'), + ), + migrations.AddField( + model_name='organizationlinkedblockinline', + name='organization_main', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='organization_linked_block', to='organization-network.Organization', verbose_name='organization'), + ), + ] diff --git a/app/organization/network/models.py b/app/organization/network/models.py index 6d9111f5..6195aeb8 100644 --- a/app/organization/network/models.py +++ b/app/organization/network/models.py @@ -60,7 +60,7 @@ PATTERN_CHOICES = [ ALIGNMENT_CHOICES = (('left', _('left')), ('left', _('left')), ('right', _('right'))) -class Organization(Named, Address, URL, AdminThumbRelatedMixin): +class Organization(Named, Address, URL, AdminThumbRelatedMixin, Orderable): """(Organization description)""" mappable_location = models.CharField(max_length=128, blank=True, null=True, help_text="This address will be used to calculate latitude and longitude. Leave blank and set Latitude and Longitude to specify the location yourself, or leave all three blank to auto-fill from the Location field.") @@ -73,10 +73,6 @@ class Organization(Named, Address, URL, AdminThumbRelatedMixin): telephone = models.CharField(_('telephone'), max_length=64, blank=True, null=True) opening_times = models.TextField(_('opening times'), blank=True) subway_access = models.TextField(_('subway access'), blank=True) - organizations_content = models.ManyToManyField('self', verbose_name=_('Linked organizations (in content)'), related_name='organizations_content', blank=True, help_text="Usefull for host organization") - organizations_footer = models.ManyToManyField('self', verbose_name=_('Linked organizations (in footer)'), related_name='organizations_footer', blank=True, help_text="Usefull for host organization") - order = models.IntegerField(_('order number'), default=10) - admin_thumb_type = 'logo' class Meta: @@ -118,6 +114,26 @@ class Organization(Named, Address, URL, AdminThumbRelatedMixin): super(Organization, self).save() +class OrganizationLinkedBlockInline(Titled, Orderable): + organization_linked = models.ForeignKey('OrganizationLinked', verbose_name=_('organization list'), related_name='organization_linked_block_inline_list', blank=True, null=True) + organization_main = models.ForeignKey('Organization', verbose_name=_('organization'), related_name='organization_linked_block', blank=True, null=True, on_delete=models.SET_NULL) + + +class OrganizationLinked(Titled): + + class Meta: + verbose_name = _('Organization Linked') + + def __str__(self): + return self.title + + +class OrganizationLinkedInline(Titled, Orderable): + + organization_list = models.ForeignKey('OrganizationLinked', verbose_name=_('organization linked'), related_name='organization_linked_inline_linked', blank=True, null=True, on_delete=models.SET_NULL) + organization = models.ForeignKey('Organization', verbose_name=_('organization'), related_name='organization_linked_inline_from', blank=True, null=True, on_delete=models.SET_NULL) + + class OrganizationPlaylist(PlaylistRelated): organization = models.ForeignKey(Organization, verbose_name=_('organization'), related_name='playlists', blank=True, null=True, on_delete=models.SET_NULL) diff --git a/app/organization/network/translation.py b/app/organization/network/translation.py index c1f038e5..4f74b06b 100644 --- a/app/organization/network/translation.py +++ b/app/organization/network/translation.py @@ -169,3 +169,21 @@ class TrainingLevelTranslationOptions(TranslationOptions): class TrainingSpecialityTranslationOptions(TranslationOptions): fields = ['name', 'description'] + + +@register(OrganizationLinked) +class OrganizationLinkedTranslationOptions(TranslationOptions): + + fields = [] + + +@register(OrganizationLinkedInline) +class OrganizationLinkedInlineTranslationOptions(TranslationOptions): + + fields = [] + + +@register(OrganizationLinkedBlockInline) +class OrganizationLinkedBlockInlineTranslationOptions(TranslationOptions): + + fields = [] diff --git a/app/organization/network/urls.py b/app/organization/network/urls.py index fcdf1660..f40a9373 100644 --- a/app/organization/network/urls.py +++ b/app/organization/network/urls.py @@ -14,4 +14,7 @@ urlpatterns = [ url("^person-list-block-autocomplete/$", permission_required('person.can_edit')(PersonListBlockAutocompleteView.as_view()), name='person-list-block-autocomplete'), url("^person-autocomplete/$", permission_required('person.can_edit')(PersonListView.as_view()), name='person-autocomplete'), url("^network/$", OrganizationListView.as_view(), name='network'), + url("^organization-linked-list-autocomplete/$", permission_required('organization.can_edit')(OrganizationLinkedListView.as_view()), name='organization-linked-list-autocomplete'), + url("^organization-linked-autocomplete/$", permission_required('organization.can_edit')(OrganizationLinkedView.as_view()), name='organization-linked-autocomplete'), + ] diff --git a/app/organization/network/views.py b/app/organization/network/views.py index 819ac924..c5bdc3b9 100644 --- a/app/organization/network/views.py +++ b/app/organization/network/views.py @@ -70,3 +70,27 @@ class OrganizationListView(ListView): context = super(OrganizationListView, self).get_context_data(**kwargs) context['organization_types'] = self.get_queryset().values_list('type__name', 'type__css_class').order_by('type__name').distinct('type__name') return context + + +class OrganizationLinkedListView(autocomplete.Select2QuerySetView): + + def get_queryset(self): + qs = OrganizationLinked.objects.all() + orga_linked_title = self.forwarded.get('title', None) + if orga_linked_title: + qs = qs.filter(title=orga_linked_title) + if self.q: + qs = qs.filter(title__istartswith=self.q) + return qs + + +class OrganizationLinkedView(autocomplete.Select2QuerySetView): + + def get_queryset(self): + qs = Organization.objects.all() + orga_name= self.forwarded.get('name', None) + if orga_name: + qs = qs.filter(name=orga_name) + if self.q: + qs = qs.filter(name__istartswith=self.q) + return qs diff --git a/app/static/src/sass/modules/_linked-organizations.scss b/app/static/src/sass/modules/_linked-organizations.scss index a412bec5..78dda38d 100644 --- a/app/static/src/sass/modules/_linked-organizations.scss +++ b/app/static/src/sass/modules/_linked-organizations.scss @@ -10,8 +10,6 @@ $module: ".linked-organizations"; &__item { display: inline-block; - width: 40px; - height: 40px; background-size: contain; background-position: center center; background-repeat: no-repeat; @@ -19,8 +17,7 @@ $module: ".linked-organizations"; @include margin(0 1 0 0); a { - width : 40px; - height : 40px; + display: inline-block; } } diff --git a/app/templates/core/inc/linked_organization_content.html b/app/templates/core/inc/linked_organization_content.html deleted file mode 100644 index dd4b613c..00000000 --- a/app/templates/core/inc/linked_organization_content.html +++ /dev/null @@ -1,16 +0,0 @@ -{% load organization_tags %} -
-
-
    - {% for loc in linked_organization_content %} - {% with loc.images|get_type:"logo_black"|first as img %} -
  • - - - -
  • - {% endwith %} - {% endfor %} -
-
-
diff --git a/app/templates/includes/footer.html b/app/templates/includes/footer.html index 78a04161..b26391ca 100644 --- a/app/templates/includes/footer.html +++ b/app/templates/includes/footer.html @@ -54,20 +54,15 @@ {{ host_organization.description }}
{% trans 'under the tutelage of' %} :

{% if linked_organization_footer %} - {% include 'core/inc/linked_organization_footer.html' %} + {% include 'pages/page/includes/linked_organization_footer.html' %} {% endif %}
{% trans 'go to' %} : - + {% if linked_organization_footer_2 %} + {% include 'pages/page/includes/linked_organization_footer_2.html' %} + {% endif %}
diff --git a/app/templates/pages/custompage.html b/app/templates/pages/custompage.html index 6473a7e5..b9cf1ab7 100644 --- a/app/templates/pages/custompage.html +++ b/app/templates/pages/custompage.html @@ -24,7 +24,7 @@ {% with page.get_ascendants|last as top_level_parent %} {% if linked_organization_content and research_slug == top_level_parent.slug %} - {% include 'core/inc/linked_organization_content.html' %} + {% include 'pages/page/includes/linked_organization_content.html' %} {% endif %} {% endwith %} diff --git a/app/templates/pages/departmentpage.html b/app/templates/pages/departmentpage.html index c83813dd..f396a9ff 100644 --- a/app/templates/pages/departmentpage.html +++ b/app/templates/pages/departmentpage.html @@ -25,8 +25,9 @@ {% endeditable %} {% endif %}--> + {{ linked_organization_content.all }} {% if linked_organization_content and research_slug == page.departmentpage.slug %} - {% include 'core/inc/linked_organization_content.html' %} + {% include 'pages/page/includes/linked_organization_content.html' %} {% endif %} {% if page.departmentpage.content %} diff --git a/app/templates/pages/page/includes/linked_organization_content.html b/app/templates/pages/page/includes/linked_organization_content.html new file mode 100644 index 00000000..11a18351 --- /dev/null +++ b/app/templates/pages/page/includes/linked_organization_content.html @@ -0,0 +1,18 @@ +{% load organization_tags %} +
+
+
    + {% for loc in linked_organization_content %} + {% if loc.images.all %} + {% with loc.images|get_type:"logo_black"|first as img %} +
  • + + + +
  • + {% endwith %} + {% endif %} + {% endfor %} +
+
+
diff --git a/app/templates/core/inc/linked_organization_footer.html b/app/templates/pages/page/includes/linked_organization_footer.html similarity index 89% rename from app/templates/core/inc/linked_organization_footer.html rename to app/templates/pages/page/includes/linked_organization_footer.html index 87e942e8..d93206bb 100644 --- a/app/templates/core/inc/linked_organization_footer.html +++ b/app/templates/pages/page/includes/linked_organization_footer.html @@ -1,8 +1,10 @@ {% load organization_tags %} {% for lof in linked_organization_footer %} + {% if lof.images.all %} {% with lof.images|get_type:"logo_white"|first as img %} {% endwith %} + {% endif %} {% endfor %} diff --git a/app/templates/pages/page/includes/linked_organization_footer_2.html b/app/templates/pages/page/includes/linked_organization_footer_2.html new file mode 100644 index 00000000..83191ddb --- /dev/null +++ b/app/templates/pages/page/includes/linked_organization_footer_2.html @@ -0,0 +1,8 @@ +{% load organization_tags %} + diff --git a/app/templates/pages/projecttopicpage.html b/app/templates/pages/projecttopicpage.html index e347dcba..369c750a 100644 --- a/app/templates/pages/projecttopicpage.html +++ b/app/templates/pages/projecttopicpage.html @@ -36,7 +36,7 @@ {% block page_content %} {% with page.get_ascendants|last as top_level_parent %} {% if linked_organization_content and research_slug == top_level_parent.slug %} - {% include 'core/inc/linked_organization_content.html' %} + {% include 'pages/page/includes/linked_organization_content.html' %} {% endif %} {% endwith %} diff --git a/app/templates/pages/teampage.html b/app/templates/pages/teampage.html index 8a28ccb9..fbd71ca8 100644 --- a/app/templates/pages/teampage.html +++ b/app/templates/pages/teampage.html @@ -22,7 +22,7 @@ {% block page_content %} {% with page.get_ascendants|last as top_level_parent %} {% if linked_organization_content and research_slug == top_level_parent.slug %} - {% include 'core/inc/linked_organization_content.html' %} + {% include 'pages/page/includes/linked_organization_content.html' %} {% endif %} {% endwith %} {% if page.teampage.sub_title %} diff --git a/app/templates/projects/project_detail.html b/app/templates/projects/project_detail.html index 50f43bfb..e5e1dfa4 100644 --- a/app/templates/projects/project_detail.html +++ b/app/templates/projects/project_detail.html @@ -47,7 +47,7 @@ {% with page.get_ascendants|last as top_level_parent %} {% if linked_organization_content and research_slug == top_level_parent.slug %} - {% include 'core/inc/linked_organization_content.html' %} + {% include 'pages/page/includes/linked_organization_content.html' %} {% endif %} {% endwith %} -- 2.39.5