From: Emilie Date: Fri, 4 Nov 2016 17:58:32 +0000 (+0100) Subject: Project : add dynamic content X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=58bde5e32b3b8b3559e6d723bd361f65605194fa;p=mezzo.git Project : add dynamic content --- diff --git a/app/organization/agenda/forms.py b/app/organization/agenda/forms.py index 96f60207..af8b12bf 100644 --- a/app/organization/agenda/forms.py +++ b/app/organization/agenda/forms.py @@ -11,16 +11,14 @@ from organization.magazine.models import Article, Topic, Brief from organization.pages.models import CustomPage from organization.agenda.models import Event, DynamicContentEvent from organization.media.models import Playlist -from organization.network.models import TeamPage -from organization.projects.models import Project - class DynamicContentEventForm(autocomplete.FutureModelForm): content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField( queryset=autocomplete.QuerySetSequence( Article.objects.all(), - CustomPage.objects.all() + CustomPage.objects.all(), + Event.objects.all() ), required=False, widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-content-event'), diff --git a/app/organization/agenda/views.py b/app/organization/agenda/views.py index 03d85d5e..acaddea1 100644 --- a/app/organization/agenda/views.py +++ b/app/organization/agenda/views.py @@ -2,8 +2,6 @@ from django.views.generic.base import TemplateView from mezzanine.conf import settings from dal import autocomplete from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView -from organization.network.models import TeamPage -from organization.projects.models import Project from organization.magazine.models import Article from organization.pages.models import CustomPage from mezzanine_agenda.models import Event @@ -34,11 +32,8 @@ class DynamicContentEventView(Select2QuerySetSequenceView): qs = autocomplete.QuerySetSequence(articles, custompage, events,) if self.q: - # This would apply the filter on all the querysets qs = qs.filter(title__icontains=self.q) - # This will limit each queryset so that they show an equal number - # of results. qs = self.mixup_querysets(qs) return qs diff --git a/app/organization/projects/admin.py b/app/organization/projects/admin.py index 9396727a..daed65c2 100644 --- a/app/organization/projects/admin.py +++ b/app/organization/projects/admin.py @@ -5,11 +5,12 @@ from django.utils.translation import ugettext_lazy as _ from mezzanine.core.admin import * from mezzanine.pages.admin import PageAdmin - +from modeltranslation.admin import TranslationTabularInline from organization.projects.models import * from organization.pages.models import * from organization.media.models import Playlist from organization.pages.admin import PageImageInline +from organization.projects.forms import DynamicContentProjectForm class ProjectLinkInline(StackedDynamicInlineAdmin): @@ -53,6 +54,22 @@ class ProjectAdmin(admin.ModelAdmin): model = Project +class ProjectRelatedTitleAdmin(TranslationTabularInline): + + model = ProjectRelatedTitle + + +class DynamicContentProjectInline(TabularDynamicInlineAdmin): + + model = DynamicContentProject + form = DynamicContentProjectForm + + class Media: + js = ( + static("mezzanine/js/admin/dynamic_inline.js"), + ) + + class ProjectAdminDisplayable(DisplayableAdmin): fieldsets = deepcopy(ProjectAdmin.fieldsets) @@ -60,7 +77,9 @@ class ProjectAdminDisplayable(DisplayableAdmin): ProjectImageInline, ProjectPlaylistInline, ProjectLinkInline, - ProjectFileInline,] + ProjectFileInline, + ProjectRelatedTitleAdmin, + DynamicContentProjectInline] filter_horizontal = ['teams', 'organizations'] list_filter = ['type', 'program', 'program_type', ] diff --git a/app/organization/projects/forms.py b/app/organization/projects/forms.py new file mode 100644 index 00000000..afe0c2d0 --- /dev/null +++ b/app/organization/projects/forms.py @@ -0,0 +1,31 @@ +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.magazine.models import Article, Topic, Brief +from organization.pages.models import CustomPage +from organization.agenda.models import Event, DynamicContentEvent +from organization.media.models import Playlist +from organization.projects.models import DynamicContentProject + + +class DynamicContentProjectForm(autocomplete.FutureModelForm): + + content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField( + queryset=autocomplete.QuerySetSequence( + Article.objects.all(), + CustomPage.objects.all(), + Event.objects.all() + ), + required=False, + widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-content-project'), + ) + + class Meta: + model = DynamicContentProject + fields = ('content_object',) diff --git a/app/organization/projects/migrations/0026_dynamiccontentproject.py b/app/organization/projects/migrations/0026_dynamiccontentproject.py new file mode 100644 index 00000000..e18669bb --- /dev/null +++ b/app/organization/projects/migrations/0026_dynamiccontentproject.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-11-04 17:33 +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-projects', '0025_auto_20161103_1825'), + ] + + operations = [ + migrations.CreateModel( + name='DynamicContentProject', + 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')), + ('project', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dynamic_content_project', to='organization-projects.Project', verbose_name='project')), + ], + options={ + 'verbose_name': 'Dynamic Content Project', + 'ordering': ('_order',), + }, + ), + ] diff --git a/app/organization/projects/migrations/0027_auto_20161104_1849.py b/app/organization/projects/migrations/0027_auto_20161104_1849.py new file mode 100644 index 00000000..efbe8b65 --- /dev/null +++ b/app/organization/projects/migrations/0027_auto_20161104_1849.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-11-04 17:49 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-projects', '0026_dynamiccontentproject'), + ] + + operations = [ + migrations.CreateModel( + name='ProjectRelatedTitle', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(blank=True, max_length=1024, null=True, verbose_name='title')), + ('project', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='related_title', to='organization-projects.Project', verbose_name='project')), + ], + options={ + 'verbose_name': 'related title', + }, + ), + migrations.AlterOrderWithRespectTo( + name='projectrelatedtitle', + order_with_respect_to='project', + ), + ] diff --git a/app/organization/projects/migrations/0028_auto_20161104_1855.py b/app/organization/projects/migrations/0028_auto_20161104_1855.py new file mode 100644 index 00000000..30d821cb --- /dev/null +++ b/app/organization/projects/migrations/0028_auto_20161104_1855.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.10 on 2016-11-04 17:55 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('organization-projects', '0027_auto_20161104_1849'), + ] + + operations = [ + migrations.AddField( + model_name='projectrelatedtitle', + name='title_en', + field=models.CharField(blank=True, max_length=1024, null=True, verbose_name='title'), + ), + migrations.AddField( + model_name='projectrelatedtitle', + name='title_fr', + field=models.CharField(blank=True, max_length=1024, null=True, verbose_name='title'), + ), + ] diff --git a/app/organization/projects/models.py b/app/organization/projects/models.py index f960eac0..66356bdb 100644 --- a/app/organization/projects/models.py +++ b/app/organization/projects/models.py @@ -196,3 +196,20 @@ class RepositorySystem(Named): class Meta: verbose_name = _('repository system') verbose_name_plural = _("repository systems") + + +class ProjectRelatedTitle(RelatedTitle): + + project = models.OneToOneField(Project, verbose_name=_('project'), related_name='related_title', blank=True, null=True, on_delete=models.SET_NULL) + + class Meta: + verbose_name = _("related title") + order_with_respect_to = "project" + + +class DynamicContentProject(DynamicContent, Orderable): + + project = models.ForeignKey(Project, verbose_name=_('project'), related_name='dynamic_content_project', blank=True, null=True, on_delete=models.SET_NULL) + + class Meta: + verbose_name = 'Dynamic Content Project' diff --git a/app/organization/projects/translation.py b/app/organization/projects/translation.py index 8398acd6..b7ce47e4 100644 --- a/app/organization/projects/translation.py +++ b/app/organization/projects/translation.py @@ -67,3 +67,15 @@ class ProjectTopicPageTranslationOptions(TranslationOptions): class ProjectDemoTranslationOptions(TranslationOptions): fields = ('title', 'description',) + + +@register(ProjectRelatedTitle) +class ProjectRelatedTitleranslationOptions(TranslationOptions): + + fields = ('title',) + + +@register(DynamicContentProject) +class DynamicContentProjectTranslationOptions(TranslationOptions): + + fields = () diff --git a/app/organization/projects/urls.py b/app/organization/projects/urls.py index 19efbc97..86bf8853 100644 --- a/app/organization/projects/urls.py +++ b/app/organization/projects/urls.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import django.views.i18n from django.conf.urls import patterns, include, url from django.conf.urls.i18n import i18n_patterns - +from django.contrib.auth.decorators import permission_required from mezzanine.core.views import direct_to_template from mezzanine.conf import settings @@ -11,4 +11,5 @@ from organization.projects.views import * urlpatterns = [ url("^project/detail/(?P.*)/$", ProjectDetailView.as_view(), name='organization-project-detail'), + url("^dynamic-content-project/$", permission_required('project.can_edit')(DynamicContentProjectView.as_view()), name='dynamic-content-project'), ] diff --git a/app/organization/projects/views.py b/app/organization/projects/views.py index abd8acdb..a6bc9154 100644 --- a/app/organization/projects/views.py +++ b/app/organization/projects/views.py @@ -1,7 +1,11 @@ from django.shortcuts import render - +from dal import autocomplete +from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView from organization.projects.models import * from organization.core.views import * +from organization.magazine.views import Article +from mezzanine_agenda.models import Event +from organization.pages.models import CustomPage class ProjectDetailView(SlugMixin, DetailView): @@ -30,3 +34,26 @@ class ProjectDetailView(SlugMixin, DetailView): elif project.topic: context['page'] = project.topic.pages.all().first() return context + + +class DynamicContentProjectView(Select2QuerySetSequenceView): + + def get_queryset(self): + + articles = Article.objects.all() + custompage = CustomPage.objects.all() + events = Event.objects.all() + + if self.q: + articles = articles.filter(title__icontains=self.q) + custompage = custompage.filter(title__icontains=self.q) + events = events.filter(title__icontains=self.q) + + qs = autocomplete.QuerySetSequence(articles, custompage, events,) + + if self.q: + qs = qs.filter(title__icontains=self.q) + + qs = self.mixup_querysets(qs) + + return qs diff --git a/app/templates/projects/project_detail.html b/app/templates/projects/project_detail.html index eaa5f064..ca31accd 100644 --- a/app/templates/projects/project_detail.html +++ b/app/templates/projects/project_detail.html @@ -294,3 +294,9 @@ {% endif %} {% endblock %} + +{% block page_related_content %} + {% with dynamic_content=project.dynamic_content_project.all object=project %} + {% include "core/inc/related_content.html" %} + {% endwith %} +{% endblock %}