From: Emilie Date: Fri, 16 Sep 2016 10:47:49 +0000 (+0200) Subject: Person list : dynamic content in page with GenericFK X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=d6e8ef30ad338a08b8c083436161ec7fa735793b;p=mezzo.git Person list : dynamic content in page with GenericFK --- diff --git a/app/local_settings.py b/app/local_settings.py index 7ac1ecef..6b1bf30d 100644 --- a/app/local_settings.py +++ b/app/local_settings.py @@ -70,11 +70,18 @@ SITE_TAGLINE = 'Institut de Recherche et de Coordination Acoustique et Musique' SILENCED_SYSTEM_CHECKS = ['fields.W342',] ADMIN_MENU_ORDER = ( - (_('Pages'), ('pages.Page', 'organization-pages.Home', 'organization-job.JobOffer')), + (_('Pages'), ('pages.Page', 'organization-pages.Home', 'organization-job.JobOffer',)), (_('Media'), ('organization-media.Video', 'organization-media.VideoCategory', 'organization-media.Audio', 'organization-media.Playlist', (_('Media Library'), 'fb_browse'),)), (_('Events'), ('mezzanine_agenda.Event', 'mezzanine_agenda.EventLocation', 'mezzanine_agenda.EventPrice', 'mezzanine_agenda.EventCategory')), (_('Magazine'), ('organization-magazine.Article', 'organization-magazine.Brief',)), - (_('Network'), ('organization-network.Organization', 'organization-network.Department', 'organization-network.Team', 'organization-network.Person', 'organization-network.Activity', 'organization-network.OrganizationType',)), + (_('Network'), ('organization-network.Organization', + 'organization-network.Department', + 'organization-network.Team', + 'organization-network.Person', + 'organization-network.Activity', + 'organization-network.OrganizationType', + 'organization-network.PersonListBlock', + )), (_('Projects'), ('organization-projects.Project','organization-projects.ProjectProgram', 'organization-projects.ProjectProgramType' )), (_('Festival'), ('organization-festival.Artist',)), (_('Users'), ('auth.User', 'auth.Group',)), diff --git a/app/organization/network/admin.py b/app/organization/network/admin.py index 582aeeb7..78ee16dd 100644 --- a/app/organization/network/admin.py +++ b/app/organization/network/admin.py @@ -1,14 +1,17 @@ from django.contrib import admin from django import forms from copy import deepcopy +from dal import autocomplete +from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView from mezzanine.core.admin import * from mezzanine.pages.admin import PageAdmin - from organization.network.models import * +from organization.network.forms import * from organization.pages.models import * from organization.core.admin import * from organization.pages.admin import PageImageInline, PageBlockInline, PageAudioInline, PageVideoInline + class OrganizationAudioInline(StackedDynamicInlineAdmin): model = OrganizationAudio @@ -114,6 +117,25 @@ class PersonAdmin(BaseTranslationModelAdmin): return res +class DynamicContentPersonListInline(TabularDynamicInlineAdmin): + + model = DynamicPersonList + form = DynamicPersonListForm + + class Media: + js = ( + static("mezzanine/js/admin/dynamic_inline.js"), + static("mezzanine/js/jquery-ui-1.9.2.min.js"), + ) + + +class PersonListBlockAdmin(admin.ModelAdmin): + + inlines = [DynamicContentPersonListInline, ] + + + + admin.site.register(Organization, OrganizationAdmin) admin.site.register(OrganizationType) admin.site.register(Department, DepartmentAdmin) @@ -121,3 +143,4 @@ admin.site.register(DepartmentPage, DepartmentPageAdmin) admin.site.register(Team, TeamAdmin) admin.site.register(TeamPage, TeamPageAdmin) admin.site.register(Person, PersonAdmin) +admin.site.register(PersonListBlock, PersonListBlockAdmin) diff --git a/app/organization/network/forms.py b/app/organization/network/forms.py new file mode 100644 index 00000000..ce6461e1 --- /dev/null +++ b/app/organization/network/forms.py @@ -0,0 +1,44 @@ +from dal import autocomplete +import dal_queryset_sequence +import dal_select2_queryset_sequence +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 +from organization.network.models import PersonListBlock, DynamicPersonList #DynamicContentPersonList, +from organization.pages.models import DynamicPersonListBlockPage + + +class DynamicPersonListForm(autocomplete.FutureModelForm): + """ + List of Person + """ + content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField( + queryset=autocomplete.QuerySetSequence( + Person.objects.all(), + ), + required=False, + widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-person-list'), + ) + + class Meta: + model = DynamicPersonList + fields = ('content_object',) + + +class DynamicContentPersonListBlockForm(autocomplete.FutureModelForm): + """ + List of PersonListBlock + """ + content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField( + queryset=autocomplete.QuerySetSequence( + PersonListBlock.objects.all(), + ), + required=False, + widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-content-person-list-block'), + ) + + class Meta: + model = DynamicPersonListBlockPage + fields = ('content_object',) diff --git a/app/organization/network/migrations/0008_auto_20160916_1129.py b/app/organization/network/migrations/0008_auto_20160916_1129.py new file mode 100644 index 00000000..c203a009 --- /dev/null +++ b/app/organization/network/migrations/0008_auto_20160916_1129.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 09:29 +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 = [ + ('contenttypes', '0002_remove_content_type_name'), + ('organization-network', '0007_auto_20160914_1818'), + ] + + operations = [ + migrations.CreateModel( + name='DynamicPersonList', + 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')), + ('object_id', models.PositiveIntegerField(editable=False, null=True, verbose_name='related object')), + ('content_type', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='content type')), + ], + options={ + 'ordering': ('_order',), + 'verbose_name': 'Dynamic Content Person List', + }, + ), + migrations.CreateModel( + name='PersonListBlock', + 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': 'Person List', + }, + ), + migrations.AddField( + model_name='dynamicpersonlist', + name='person_list_block', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dynamic_person_list', to='organization-network.PersonListBlock', verbose_name='Person List Block'), + ), + ] diff --git a/app/organization/network/models.py b/app/organization/network/models.py index 26b7fd3a..d22c3da3 100644 --- a/app/organization/network/models.py +++ b/app/organization/network/models.py @@ -227,10 +227,21 @@ class PersonBlock(Block): person = models.ForeignKey(Person, verbose_name=_('person'), related_name='blocks', blank=True, null=True, on_delete=models.SET_NULL) -# class PersonListBlock(Titled): -# -# class Meta: -# verbose_name = _('Person List') +class PersonListBlock(Titled): + + class Meta: + verbose_name = _('Person List') + + def __str__(self): + return self.title + + +class DynamicPersonList(DynamicContent, Orderable): + + person_list_block = models.ForeignKey("PersonListBlock", verbose_name=_('Person List Block'), related_name='dynamic_person_list', blank=True, null=True, on_delete=models.SET_NULL) + + class Meta: + verbose_name = 'Dynamic Content Person List' class ActivityStatus(Named): diff --git a/app/organization/network/translation.py b/app/organization/network/translation.py index 8f330ee0..faf9564d 100644 --- a/app/organization/network/translation.py +++ b/app/organization/network/translation.py @@ -103,3 +103,15 @@ class OrganizationImageTranslationOptions(TranslationOptions): class OrganizationBlockTranslationOptions(TranslationOptions): pass + + +@register(DynamicPersonList) +class DynamicPersonListTranslationOptions(TranslationOptions): + + pass + + +@register(PersonListBlock) +class PersonListBlockTranslationOptions(TranslationOptions): + + pass diff --git a/app/organization/network/urls.py b/app/organization/network/urls.py index 97281b13..01e7e048 100644 --- a/app/organization/network/urls.py +++ b/app/organization/network/urls.py @@ -13,4 +13,7 @@ from organization.network.views import * urlpatterns = [ url(r'^(?P.*)/teams/$', TeamListView.as_view(), name="organization-network-team-list"), url(r'^person/(?P.*)/$', PersonDetailView.as_view(), name="organization-network-person-detail"), -] + url("^dynamic-person-list/$", DynamicPersonListView.as_view(), name='dynamic-person-list'), + url("^dynamic-content-person-list-block/$", DynamicContentPersonListBlockView.as_view(), name='dynamic-content-person-list-block'), + + ] diff --git a/app/organization/network/views.py b/app/organization/network/views.py index bc01c20c..68ae2403 100644 --- a/app/organization/network/views.py +++ b/app/organization/network/views.py @@ -1,5 +1,6 @@ from django.shortcuts import render - +from dal import autocomplete +from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView from organization.network.models import * from organization.core.views import * @@ -59,3 +60,29 @@ class PersonDetailView(SlugMixin, DetailView): model = Person template_name='team/person_detail.html' context_object_name = 'person' + + +class DynamicPersonListView(Select2QuerySetSequenceView): + + def get_queryset(self): + persons = Person.objects.all() + if self.q: + persons = persons.filter(person_title__icontains=self.q) + qs = autocomplete.QuerySetSequence(persons) + if self.q: + qs = qs.filter(person_title__icontains=self.q) + qs = self.mixup_querysets(qs) + return qs + + +class DynamicContentPersonListBlockView(Select2QuerySetSequenceView): + + def get_queryset(self): + person_list_blocks = PersonListBlock.objects.all() + if self.q: + person_list_blocks = person_list_blocks.filter(title__icontains=self.q) + qs = autocomplete.QuerySetSequence(person_list_blocks) + if self.q: + qs = qs.filter(title__icontains=self.q) + qs = self.mixup_querysets(qs) + return qs diff --git a/app/organization/pages/admin.py b/app/organization/pages/admin.py index d578689a..5b9cb168 100644 --- a/app/organization/pages/admin.py +++ b/app/organization/pages/admin.py @@ -7,10 +7,10 @@ from organization.pages.models import * from organization.pages.models import ( DynamicContentHomeSlider, DynamicContentHomeBody, - Home + Home, ) -from organization.pages.forms import DynamicContentHomeSliderForm, DynamicContentHomeBodyForm - +from organization.pages.forms import * +from organization.network.forms import * class PageBlockInline(StackedDynamicInlineAdmin): @@ -39,9 +39,20 @@ class PageLinkInline(StackedDynamicInlineAdmin): model = PageLink +class DynamicContentPersonListBlockInline(TabularDynamicInlineAdmin): + + model = DynamicPersonListBlockPage + form = DynamicContentPersonListBlockForm + + class Media: + js = ( + static("mezzanine/js/admin/dynamic_inline.js"), + ) + + class CustomPageAdmin(PageAdmin): - inlines = [PageBlockInline, PageImageInline, PageAudioInline, PageVideoInline, PageLinkInline] + inlines = [PageBlockInline, PageImageInline, PageAudioInline, PageVideoInline, PageLinkInline, DynamicContentPersonListBlockInline] class DynamicContentHomeSliderInline(TabularDynamicInlineAdmin): @@ -67,5 +78,10 @@ class HomeAdminDisplayable(BaseTranslationModelAdmin): + + + + admin.site.register(CustomPage, CustomPageAdmin) admin.site.register(Home, HomeAdminDisplayable) +# admin.site.register(PersonListBlock, PersonListBlockAdmin) diff --git a/app/organization/pages/migrations/0003_dynamicpersonlistblockpage.py b/app/organization/pages/migrations/0003_dynamicpersonlistblockpage.py new file mode 100644 index 00000000..77015c8f --- /dev/null +++ b/app/organization/pages/migrations/0003_dynamicpersonlistblockpage.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2016-09-16 09:29 +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 = [ + ('contenttypes', '0002_remove_content_type_name'), + ('pages', '0004_auto_20160804_1547'), + ('organization-pages', '0002_auto_20160914_1838'), + ] + + operations = [ + migrations.CreateModel( + name='DynamicPersonListBlockPage', + 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')), + ('object_id', models.PositiveIntegerField(editable=False, null=True, verbose_name='related object')), + ('content_type', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='content type')), + ('page', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='person_list_blocks', to='pages.Page', verbose_name='Page')), + ], + options={ + 'ordering': ('_order',), + 'verbose_name': 'Person List', + }, + ), + ] diff --git a/app/organization/pages/models.py b/app/organization/pages/models.py index 8561cf29..bfdb4868 100644 --- a/app/organization/pages/models.py +++ b/app/organization/pages/models.py @@ -86,3 +86,13 @@ class Home(Displayable): def get_absolute_url(self): return reverse("organization-home") + + verbose_name = _('Person List') + + +class DynamicPersonListBlockPage(DynamicContent, Orderable): + + page = models.ForeignKey(Page, verbose_name=_('Page'), related_name='person_list_blocks', blank=True, null=True, on_delete=models.SET_NULL) + + class Meta: + verbose_name = _('Person List') diff --git a/app/organization/pages/translation.py b/app/organization/pages/translation.py index d84002dc..4ad2d9f7 100644 --- a/app/organization/pages/translation.py +++ b/app/organization/pages/translation.py @@ -56,3 +56,8 @@ class PageAudioTranslationOptions(TranslationOptions): class PageLinkTranslationOptions(TranslationOptions): pass + +@register(DynamicPersonListBlockPage) +class DynamicPersonListBlockPageTranslationOptions(TranslationOptions): + + pass diff --git a/app/organization/pages/urls.py b/app/organization/pages/urls.py index 4edb52df..12d58fad 100644 --- a/app/organization/pages/urls.py +++ b/app/organization/pages/urls.py @@ -6,11 +6,7 @@ from django.contrib import admin from mezzanine.core.views import direct_to_template from mezzanine.conf import settings -from organization.pages.views import ( - DynamicContentHomeSliderView, - DynamicContentHomeBodyView, - HomeView -) +from organization.pages.views import * _slash = "/" if settings.APPEND_SLASH else "" @@ -19,4 +15,5 @@ urlpatterns = [ url("^dynamic-content-home-slider/$", DynamicContentHomeSliderView.as_view(), name='dynamic-content-home-slider'), url("^dynamic-content-home-body/$", DynamicContentHomeBodyView.as_view(), name='dynamic-content-home-body'), url("^home/$", HomeView.as_view(), name='organization-home'), + ]