]> git.parisson.com Git - mezzo.git/commitdiff
Abstract DynamicContent + DynamicContentHomeSlider + DynamicContentHomeBody
authorEmilie <zawadzki@ircam.fr>
Thu, 18 Aug 2016 17:23:39 +0000 (19:23 +0200)
committerEmilie <zawadzki@ircam.fr>
Thu, 18 Aug 2016 17:23:39 +0000 (19:23 +0200)
19 files changed:
app/local_settings.py
app/organization/core/models.py
app/organization/magazine/forms.py
app/organization/media/views.py
app/organization/pages/__init__.py [new file with mode: 0644]
app/organization/pages/admin.py [new file with mode: 0644]
app/organization/pages/apps.py [new file with mode: 0644]
app/organization/pages/forms.py [new file with mode: 0644]
app/organization/pages/migrations/0001_initial.py [new file with mode: 0644]
app/organization/pages/migrations/0002_auto_20160818_1821.py [new file with mode: 0644]
app/organization/pages/migrations/0003_dynamiccontenthomebody.py [new file with mode: 0644]
app/organization/pages/migrations/__init__.py [new file with mode: 0644]
app/organization/pages/models.py [new file with mode: 0644]
app/organization/pages/tests.py [new file with mode: 0644]
app/organization/pages/translation.py [new file with mode: 0644]
app/organization/pages/urls.py [new file with mode: 0644]
app/organization/pages/views.py [new file with mode: 0644]
app/organization/urls.py
app/settings.py

index 63179b76ea522bb3c30cb2c128811cabd414d0f6..ce39e804ccc94bf00510a9e83ca3a41d0c6f3eb0 100644 (file)
@@ -69,7 +69,7 @@ SITE_TAGLINE = 'Institut de Recherche et de Coordination Acoustique et Musique'
 SILENCED_SYSTEM_CHECKS = ['fields.W342',]
 
 ADMIN_MENU_ORDER = (
-    (_('Pages'), ('pages.Page', 'organization-featured.Featured',)),
+    (_('Pages'), ('pages.Page', 'organization-featured.Featured', 'organization-pages.Home')),
     (_('Media'), ('organization-media.Video', 'organization-media.VideoCategory', 'organization-media.Audio', 'organization-media.Playlist',  'organization-media.Photo', (_('Media Library'), 'fb_browse'),)),
     (_('Events'), ('mezzanine_agenda.Event', 'mezzanine_agenda.EventLocation', 'mezzanine_agenda.EventCategory', 'mezzanine_agenda.EventPrice',)),
     (_('Magazine'), ('organization-magazine.Article', 'organization-magazine.Brief',)),
index eca58a775eb16cdcd7c6b84777ee0b15bf901e36..118ddd463de185df7a92a3a58f0f15d043444c3c 100644 (file)
@@ -2,6 +2,8 @@ from django.db import models
 from django.conf import settings
 from django.utils.translation import ugettext_lazy as _
 from django.core.urlresolvers import reverse, reverse_lazy
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes.fields import GenericForeignKey
 
 from mezzanine.pages.models import Page, RichText
 from mezzanine.core.fields import RichTextField, OrderField, FileField
@@ -81,6 +83,29 @@ class Block(RichText, Titled, Orderable):
         abstract = True
 
 
+class DynamicContent(models.Model):
+
+    # used for autocomplete but hidden in admin
+    content_type = models.ForeignKey(
+        ContentType,
+        verbose_name=_('content type'),
+        null=True,
+        blank=True,
+        editable=False,
+    )
+
+    # used for autocomplete but hidden in admin
+    object_id = models.PositiveIntegerField(
+        verbose_name=_('related object'),
+        null=True,
+        editable=False,
+    )
+
+    content_object = GenericForeignKey('content_type', 'object_id')
+
+    class Meta:
+        abstract = True
+
 class Image(Description, Orderable):
 
     file = FileField(_("Image"), max_length=1024, format="Image", upload_to="images")
index b47fb511acbce6162d29ce87b9bd8471a2098ad4..0a9768ca25a1f926cc826926afce10369e8652ca 100644 (file)
@@ -9,17 +9,11 @@ from mezzanine_agenda.models import Event
 
 class BriefForm(autocomplete.FutureModelForm):
 
-    # selected_object = forms.ModelChoiceField(
-    #     queryset=ContentType.objects.all(),
-    #     widget=autocomplete.ModelSelect2(url='object-autocomplete')
-    # )
-
     content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField(
         queryset=autocomplete.QuerySetSequence(
             Article.objects.all(),
             Event.objects.all(),
             BasicPage.objects.all(),
-            # ContentType.objects.all(),
         ),
         required=False,
         widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('object-autocomplete'),
index 933be23de7685302eb14f693a16c591a592defa9..f55156b20ae32ec1f9dcf6b596a6b3d88aadd5d7 100644 (file)
@@ -2,7 +2,10 @@ from django.shortcuts import render
 
 from organization.media.models import *
 from organization.core.views import *
-
+from dal import autocomplete
+from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView
+from mezzanine_agenda.models import Event
+from organization.magazine.models import Article, Topic, Brief
 
 class VideoListView(ListView):
 
diff --git a/app/organization/pages/__init__.py b/app/organization/pages/__init__.py
new file mode 100644 (file)
index 0000000..21dc396
--- /dev/null
@@ -0,0 +1,10 @@
+"""
+Provides abstract models and admin features used throughout the various
+Mezzanine apps.
+"""
+from __future__ import unicode_literals
+
+from mezzanine import __version__  # noqa
+
+
+default_app_config = 'organization.pages.apps.OrganizationPagesConfig'
diff --git a/app/organization/pages/admin.py b/app/organization/pages/admin.py
new file mode 100644 (file)
index 0000000..e0ae08e
--- /dev/null
@@ -0,0 +1,28 @@
+from django.contrib import admin
+
+from django.contrib import admin
+from copy import deepcopy
+from mezzanine.core.admin import *
+from mezzanine.pages.admin import PageAdmin
+from organization.core.models import *
+from organization.pages.models import DynamicContentHomeSlider, DynamicContentHomeBody, Home
+from organization.pages.forms import DynamicContentHomeSliderForm, DynamicContentHomeBodyForm
+
+# Register your models here.
+
+class DynamicContentHomeSliderInline(StackedDynamicInlineAdmin):
+
+    model = DynamicContentHomeSlider
+    form = DynamicContentHomeSliderForm
+
+class DynamicContentHomeBodyInline(StackedDynamicInlineAdmin):
+
+    model = DynamicContentHomeBody
+    form = DynamicContentHomeBodyForm
+
+class HomeAdminDisplayable(BaseTranslationModelAdmin):
+
+    inlines = [DynamicContentHomeSliderInline, DynamicContentHomeBodyInline  ]
+
+
+admin.site.register(Home, HomeAdminDisplayable)
diff --git a/app/organization/pages/apps.py b/app/organization/pages/apps.py
new file mode 100644 (file)
index 0000000..f79213e
--- /dev/null
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+
+from django.apps import AppConfig
+
+class OrganizationPagesConfig(AppConfig):
+    name = 'organization.pages'
+    label = 'organization-pages'
diff --git a/app/organization/pages/forms.py b/app/organization/pages/forms.py
new file mode 100644 (file)
index 0000000..8b5e973
--- /dev/null
@@ -0,0 +1,42 @@
+from dal import autocomplete
+
+import dal_queryset_sequence
+import dal_select2_queryset_sequence
+
+from organization.magazine.models import Article, Topic, Brief
+from organization.core.models import BasicPage
+from mezzanine_agenda.models import Event
+from organization.pages.models import DynamicContentHomeSlider, DynamicContentHomeBody
+
+class DynamicContentHomeSliderForm(autocomplete.FutureModelForm):
+
+    content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField(
+        queryset=autocomplete.QuerySetSequence(
+            Article.objects.all(),
+            Event.objects.all(),
+            BasicPage.objects.all(),
+        ),
+        required=False,
+        widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-content-home-slider'),
+    )
+
+    class Meta:
+        model = DynamicContentHomeSlider
+        fields = ('__all__')
+
+class DynamicContentHomeBodyForm(autocomplete.FutureModelForm):
+
+    content_object = dal_queryset_sequence.fields.QuerySetSequenceModelField(
+        queryset=autocomplete.QuerySetSequence(
+            Article.objects.all(),
+            Event.objects.all(),
+            BasicPage.objects.all(),
+            Brief.objects.all(),
+        ),
+        required=False,
+        widget=dal_select2_queryset_sequence.widgets.QuerySetSequenceSelect2('dynamic-content-home-body'),
+    )
+
+    class Meta:
+        model = DynamicContentHomeBody
+        fields = ('__all__')
diff --git a/app/organization/pages/migrations/0001_initial.py b/app/organization/pages/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..aa7b755
--- /dev/null
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-18 15:18
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('sites', '0002_alter_domain_unique'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='DynamicContentHomeSlider',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('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={
+                'verbose_name': 'Dynamic Content Home Slider',
+            },
+        ),
+        migrations.CreateModel(
+            name='Home',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('keywords_string', models.CharField(blank=True, editable=False, max_length=500)),
+                ('title', models.CharField(max_length=500, verbose_name='Title')),
+                ('slug', models.CharField(blank=True, help_text='Leave blank to have the URL auto-generated from the title.', max_length=2000, null=True, verbose_name='URL')),
+                ('_meta_title', models.CharField(blank=True, help_text='Optional title to be used in the HTML title tag. If left blank, the main title field will be used.', max_length=500, null=True, verbose_name='Title')),
+                ('description', models.TextField(blank=True, verbose_name='Description')),
+                ('gen_description', models.BooleanField(default=True, help_text='If checked, the description will be automatically generated from content. Uncheck if you want to manually set a custom description.', verbose_name='Generate description')),
+                ('created', models.DateTimeField(editable=False, null=True)),
+                ('updated', models.DateTimeField(editable=False, null=True)),
+                ('status', models.IntegerField(choices=[(1, 'Draft'), (2, 'Published')], default=2, help_text='With Draft chosen, will only be shown for admin users on the site.', verbose_name='Status')),
+                ('publish_date', models.DateTimeField(blank=True, db_index=True, help_text="With Published chosen, won't be shown until this time", null=True, verbose_name='Published from')),
+                ('expiry_date', models.DateTimeField(blank=True, help_text="With Published chosen, won't be shown after this time", null=True, verbose_name='Expires on')),
+                ('short_url', models.URLField(blank=True, null=True)),
+                ('in_sitemap', models.BooleanField(default=True, verbose_name='Show in sitemap')),
+                ('site', models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.Site')),
+            ],
+            options={
+                'verbose_name': 'Home',
+            },
+        ),
+        migrations.AddField(
+            model_name='dynamiccontenthomeslider',
+            name='home',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization-pages.Home', verbose_name='home'),
+        ),
+    ]
diff --git a/app/organization/pages/migrations/0002_auto_20160818_1821.py b/app/organization/pages/migrations/0002_auto_20160818_1821.py
new file mode 100644 (file)
index 0000000..001ed94
--- /dev/null
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-18 16:21
+from __future__ import unicode_literals
+
+from django.db import migrations
+import mezzanine.core.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('organization-pages', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='dynamiccontenthomeslider',
+            options={'ordering': ('_order',), 'verbose_name': 'Dynamic Content Home Slider'},
+        ),
+        migrations.AddField(
+            model_name='dynamiccontenthomeslider',
+            name='_order',
+            field=mezzanine.core.fields.OrderField(null=True, verbose_name='Order'),
+        ),
+    ]
diff --git a/app/organization/pages/migrations/0003_dynamiccontenthomebody.py b/app/organization/pages/migrations/0003_dynamiccontenthomebody.py
new file mode 100644 (file)
index 0000000..c063e8c
--- /dev/null
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-18 16:55
+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-pages', '0002_auto_20160818_1821'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='DynamicContentHomeBody',
+            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')),
+                ('home', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='organization-pages.Home', verbose_name='home')),
+            ],
+            options={
+                'ordering': ('_order',),
+                'verbose_name': 'Dynamic Content Home Body',
+            },
+        ),
+    ]
diff --git a/app/organization/pages/migrations/__init__.py b/app/organization/pages/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app/organization/pages/models.py b/app/organization/pages/models.py
new file mode 100644 (file)
index 0000000..d604108
--- /dev/null
@@ -0,0 +1,25 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+from django.core.urlresolvers import reverse, reverse_lazy
+from mezzanine.core.models import Displayable, Slugged, Orderable
+from organization.core.models import DynamicContent
+
+
+class DynamicContentHomeSlider(DynamicContent, Orderable):
+
+    home = models.ForeignKey("home", verbose_name=_('home'), blank=True, null=True, on_delete=models.SET_NULL)
+
+    class Meta:
+        verbose_name = 'Dynamic Content Home Slider'
+
+class DynamicContentHomeBody(DynamicContent, Orderable):
+
+    home = models.ForeignKey("home", verbose_name=_('home'), blank=True, null=True, on_delete=models.SET_NULL)
+
+    class Meta:
+        verbose_name = 'Dynamic Content Home Body'
+
+class Home(Displayable):
+
+    class Meta:
+        verbose_name = 'Home'
diff --git a/app/organization/pages/tests.py b/app/organization/pages/tests.py
new file mode 100644 (file)
index 0000000..7ce503c
--- /dev/null
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/app/organization/pages/translation.py b/app/organization/pages/translation.py
new file mode 100644 (file)
index 0000000..6b67899
--- /dev/null
@@ -0,0 +1,19 @@
+from modeltranslation.translator import translator, register, TranslationOptions
+from mezzanine.pages.models import Page, RichText
+from mezzanine.pages.translation import TranslatedRichText
+from organization.pages.models import *
+
+@register(Home)
+class HomeTranslationOptions(TranslationOptions):
+
+    pass
+
+@register(DynamicContentHomeSlider)
+class DynamicContentHomeSliderOptions(TranslationOptions):
+
+    pass
+
+@register(DynamicContentHomeBody)
+class DynamicContentHomeBodyOptions(TranslationOptions):
+
+    pass
diff --git a/app/organization/pages/urls.py b/app/organization/pages/urls.py
new file mode 100644 (file)
index 0000000..cd440ab
--- /dev/null
@@ -0,0 +1,17 @@
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns, include, url
+from django.conf.urls.i18n import i18n_patterns
+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
+
+_slash = "/" if settings.APPEND_SLASH else ""
+
+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'),
+]
+'dynamic-content-home-body'
diff --git a/app/organization/pages/views.py b/app/organization/pages/views.py
new file mode 100644 (file)
index 0000000..c5227fc
--- /dev/null
@@ -0,0 +1,59 @@
+from django.shortcuts import render
+
+# Create your views here.
+from dal import autocomplete
+from dal_select2_queryset_sequence.views import Select2QuerySetSequenceView
+from mezzanine_agenda.models import Event
+from organization.core.models import BasicPage
+from organization.magazine.models import Article, Topic, Brief
+
+
+class DynamicContentHomeSliderView(Select2QuerySetSequenceView):
+    def get_queryset(self):
+
+        articles = Article.objects.all()
+        basicpage = BasicPage.objects.all()
+        events = Event.objects.all()
+
+        if self.q:
+            articles = articles.filter(title__icontains=self.q)
+            basicpage = basicpage.filter(title__icontains=self.q)
+            events = events.filter(title__icontains=self.q)
+
+        qs = autocomplete.QuerySetSequence(articles, basicpage, 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
+
+class DynamicContentHomeBodyView(Select2QuerySetSequenceView):
+    def get_queryset(self):
+
+        articles = Article.objects.all()
+        basicpage = BasicPage.objects.all()
+        events = Event.objects.all()
+        briefs = Brief.objects.all()
+
+        if self.q:
+            articles = articles.filter(title__icontains=self.q)
+            basicpage = basicpage.filter(title__icontains=self.q)
+            events = events.filter(title__icontains=self.q)
+            briefs = briefs.filter(title__icontains=self.q)
+
+        qs = autocomplete.QuerySetSequence(articles, basicpage, events, briefs)
+
+        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
index b8cfecb2474b18a03fbf8631afd8410ab7cc8d98..145430bdd777e6c6039f453b73ba02924429c2bf 100644 (file)
@@ -13,6 +13,7 @@ from mezzanine.conf import settings
 
 urlpatterns = [
     url("^", include('organization.core.urls')),
+    url("^", include('organization.pages.urls')),
     url("^", include('organization.featured.urls')),
     url("^", include('organization.festival.urls')),
     url("^", include('organization.magazine.urls')),
index 0d44c21e7a430a78d4b2a0af6b03f6d3955bf1a0..7cd057a36d92df08d9aa10096f58c918318c70f9 100644 (file)
@@ -227,6 +227,7 @@ INSTALLED_APPS = [
     "mezzanine_agenda",
 #    "orderable",
     "organization.core",
+    "organization.pages",
     "organization.team",
     "organization.festival",
     "organization.magazine",