]> git.parisson.com Git - mezzo.git/commitdiff
Autocomplete Light + Uninstalled Orderable
authorEmilie <zawadzki@ircam.fr>
Wed, 17 Aug 2016 17:34:13 +0000 (19:34 +0200)
committerEmilie <zawadzki@ircam.fr>
Wed, 17 Aug 2016 17:34:13 +0000 (19:34 +0200)
13 files changed:
app/organization/magazine/admin.py
app/organization/magazine/migrations/0012_auto_20160812_1738.py [new file with mode: 0644]
app/organization/magazine/migrations/0013_auto_20160812_1813.py [new file with mode: 0644]
app/organization/magazine/models.py
app/organization/magazine/urls.py
app/organization/magazine/views.py
app/scripts/app.sh
app/settings.py
app/templates/admin/base_site.html
app/templates/core/admin/base_site.html [new file with mode: 0644]
app/templates/includes/footer_scripts.html
requirements-dev.txt
requirements.txt

index 2693a7357e84aca9bad2569068344c7f74905032..b1dd75623e826e5f18d7287d84cd72163dbb1065 100644 (file)
@@ -3,8 +3,8 @@ from django import forms
 from copy import deepcopy
 from mezzanine.core.admin import *
 from mezzanine.pages.admin import PageAdmin
-from orderable.admin import OrderableAdmin, OrderableTabularInline
-from organization.magazine.models import Article, Brief, Topic, ArticleImage
+#from orderable.admin import OrderableTabularInline #OrderableAdmin,
+from organization.magazine.models import Article, Brief, Topic, ArticleImage, BriefForm
 
 
 class ArticleImageInline(TabularDynamicInlineAdmin):
@@ -25,16 +25,20 @@ class ArticleAdminDisplayable(DisplayableAdmin):
     inlines = [ArticleImageInline,]
 
 
-class BriefAdmin(OrderableTabularInline):
+class BriefAdmin(admin.ModelAdmin): #OrderableTabularInline
 
     model = Brief
 
 
-class BriefAdminDisplayable(BaseTranslationModelAdmin, OrderableAdmin):
+class BriefAdminDisplayable(BaseTranslationModelAdmin,): #, OrderableAdmin
 
-    list_display = ('title', 'local_content', 'sort_order_display',)
+    #list_display = ('title', 'local_content', 'sort_order_display',)
+    form = BriefForm
     fieldsets = deepcopy(BriefAdmin.fieldsets)
 
+    # form = BriefForm
+    # form = autocomplete_light.modelform_factory(Brief)
+
 
 admin.site.register(Article, ArticleAdminDisplayable)
 admin.site.register(Brief, BriefAdminDisplayable)
diff --git a/app/organization/magazine/migrations/0012_auto_20160812_1738.py b/app/organization/magazine/migrations/0012_auto_20160812_1738.py
new file mode 100644 (file)
index 0000000..047fdec
--- /dev/null
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-12 15:38
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contenttypes', '0002_remove_content_type_name'),
+        ('organization-magazine', '0011_articleimage'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='TestModel',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=200)),
+                ('object_id', models.PositiveIntegerField(blank=True, editable=False, null=True)),
+                ('content_type', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
+            ],
+        ),
+        migrations.AddField(
+            model_name='brief',
+            name='content_type',
+            field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType'),
+        ),
+        migrations.AddField(
+            model_name='brief',
+            name='object_id',
+            field=models.PositiveIntegerField(blank=True, editable=False, null=True),
+        ),
+    ]
diff --git a/app/organization/magazine/migrations/0013_auto_20160812_1813.py b/app/organization/magazine/migrations/0013_auto_20160812_1813.py
new file mode 100644 (file)
index 0000000..7bcdb9e
--- /dev/null
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-08-12 16:13
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('organization-magazine', '0012_auto_20160812_1738'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='testmodel',
+            name='content_type',
+        ),
+        migrations.AlterField(
+            model_name='brief',
+            name='content_type',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='content page'),
+        ),
+        migrations.AlterField(
+            model_name='brief',
+            name='object_id',
+            field=models.PositiveIntegerField(null=True, verbose_name='related object'),
+        ),
+        migrations.DeleteModel(
+            name='TestModel',
+        ),
+    ]
index f53d79ecab017cb1c2e80f5a9f53cbaefb24331d..aa388d007cef3982ca9db3a8dcc1e2ebe3c95c0e 100644 (file)
@@ -1,16 +1,23 @@
 from __future__ import unicode_literals
 
 from django.db import models
+from django import forms
+from django.contrib.contenttypes.fields import GenericForeignKey
+from django.contrib.contenttypes.models import ContentType
 from django.utils.translation import ugettext_lazy as _
 from django.core.urlresolvers import reverse, reverse_lazy
+from dal import autocomplete
 from mezzanine.core.models import RichText, Displayable, Slugged
 from mezzanine.pages.models import Page
 from mezzanine.blog.models import BlogPost
-from orderable.models import Orderable
+#from orderable.models import Orderable
+# from autocomplete.dal_queryset_sequence.fields import (
+#         QuerySetSequenceModelField,
+#         QuerySetSequenceModelMultipleField,
+#     )
 from organization.core.models import Named, Description, Image
 from organization.media.models import Photo
 
-
 class ArticleImage(Image):
 
     article_fk = models.ForeignKey("Article", verbose_name=_('article'))
@@ -34,17 +41,68 @@ class Article(BlogPost, Photo):
         verbose_name = _('article')
 
 
-class Brief(Displayable, RichText, Orderable):
+class Brief(Displayable, RichText): #Orderable
 
     text_button = models.CharField(blank=True, max_length=150, null=False, verbose_name='text button')
     local_content = models.URLField(blank=False, max_length=1000, null=False, verbose_name='local content')
 
+    limit = models.Q(app_label='organization-magazine', model='article') | \
+        models.Q(app_label='organization-magazine', model='topic')
+    content_type = models.ForeignKey(
+        ContentType,
+        verbose_name=_('content page'),
+        limit_choices_to=limit,
+        null=True,
+        blank=True,
+    )
+    object_id = models.PositiveIntegerField(
+        verbose_name=_('related object'),
+        null=True,
+    )
+    content_object = GenericForeignKey('content_type', 'object_id')
+
+
     def get_absolute_url(self):
         return self.local_content
 
     class Meta:
         verbose_name = _('brief')
-        ordering = ['sort_order']
+        #ordering = ['sort_order']
+
+
+
+# class BriefForm(forms.ModelForm):
+#
+#     selected_object = forms.ModelChoiceField(
+#         queryset=ContentType.objects.all(),
+#         widget=autocomplete.ModelSelect2(url='object-autocomplete')
+#     )
+#
+#     class Meta:
+#         model = Brief
+#         fields = ('__all__')
+
+class BriefForm(autocomplete.FutureModelForm):
+
+    selected_object = forms.ModelChoiceField(
+        queryset=ContentType.objects.all(),
+        widget=autocomplete.ModelSelect2(url='object-autocomplete')
+    )
+
+    # content_object = autocomplete.QuerySetSequenceModelField(
+    #     queryset=autocomplete.QuerySetSequence(
+    #         #Article.objects.all(),
+    #         #Topic.objects.all(),
+    #         #ContentType.objects.all(),
+    #     ),
+    #     required=False,
+    #     widget=autocomplete.QuerySetSequenceSelect2('object-autocomplete'),
+    # )
+
+    class Meta:
+        model = Brief
+        fields = ('__all__')
+
 
 class Topic(Page, RichText):
     """Topic for magazine menu"""
index 951be16a825bcf9ad0915bf39ddbc37efd8ed6ec..effc824c6060e33050481f23ebabf644bde007e1 100644 (file)
@@ -15,4 +15,9 @@ urlpatterns = [
     url("^article/$", ArticleListView.as_view(), name="magazine-article-list"),
     url("^article/detail/(?P<slug>.*)%s$" % _slash, ArticleDetailView.as_view(), name="magazine-article-detail"),
     url("^topic/detail/(?P<slug>.*)%s$" % _slash, TopicDetailView.as_view(), name='topic-detail'),
+    url(
+        r'^object-autocomplete/$',
+        ObjectAutocomplete.as_view(),
+        name='object-autocomplete',
+    ),
 ]
index a039256c2023034bcadf19dd688ec2cd17eaf8a3..cfb0326e42542157f639df4ecaeb62c7ab9c57aa 100644 (file)
@@ -3,8 +3,11 @@ from django.shortcuts import render
 from django.utils import timezone
 #from django.views.generic import *
 from django.views.generic import DetailView, ListView, TemplateView
+from django.contrib.contenttypes.models import ContentType
 from django.views.generic.base import *
 from django.shortcuts import get_object_or_404
+from itertools import chain
+from dal import autocomplete
 
 from organization.magazine.models import Article, Topic, Brief
 from organization.team.models import Department
@@ -79,3 +82,29 @@ class TopicDetailView(SlugMixin, DetailView):
     def get_context_data(self, **kwargs):
         context = super(TopicDetailView, self).get_context_data(**kwargs)
         return context
+
+class ObjectAutocomplete(autocomplete.Select2QuerySetView):
+    def get_queryset(self):
+
+        #qs = chain(Topic.objects.all(), Article.objects.all())
+        #qs = Article.objects.all()
+        articles = Article.objects.all()
+        topics = Topic.objects.all()
+
+
+        if self.q:
+            #qs = qs.filter(name__istartswith=self.q)
+            articles = articles.filter(name__icontains=self.q)
+            topics = topics.filter(name__icontains=self.q)
+
+        qs = QuerySetSequence(articles, topics)
+
+        if self.q:
+            # This would apply the filter on all the querysets
+            qs = qs.filter(name__icontains=self.q)
+
+        # This will limit each queryset so that they show an equal number
+        # of results.
+        qs = self.mixup_querysets(qs)
+        print(qs)
+        return qs
index 7bdf3e503a21f2864fe130d57417833158ed5918..3a9d01ba41bce2fe6e74a63da0c53153d77b50bf 100644 (file)
@@ -21,6 +21,7 @@ patterns='*.js;*.css;*.jpg;*.jpeg;*.gif;*.png;*.svg;*.ttf;*.eot;*.woff;*.woff2'
 # pip install psycopg2
 # pip install -U https://forge.ircam.fr/p/django-eve/source/download/dev/
 # pip install -U https://github.com/stephenmcd/grappelli-safe/archive/dynamic_stacked.zip
+# pip install django-querysetsequence
 
 chown -R $uid:$gid $media
 
index a7062cfc1395963edc8732cce12a9e4ea8e648c1..f0e6d78245012a4157e0a153143e5607d54e615d 100644 (file)
@@ -199,6 +199,9 @@ ROOT_URLCONF = "urls"
 
 INSTALLED_APPS = [
     "modeltranslation",
+    "dal",
+    "dal_select2",
+    "dal_queryset_sequence",
     "django.contrib.admin",
     "django.contrib.auth",
     "django.contrib.contenttypes",
@@ -222,7 +225,7 @@ INSTALLED_APPS = [
     'djangobower',
     "meta",
     "mezzanine_agenda",
-    "orderable",
+#    "orderable",
     "organization.core",
     "organization.team",
     "organization.festival",
index eb23ab24b2751da7434d7b923f9678fd0bc01dbe..e601e21edc91735106ba1d786c2e2b496993f50f 100644 (file)
@@ -30,7 +30,6 @@
     window.__admin_menu_collapsed = {{ settings.ADMIN_MENU_COLLAPSED|lower }};
     window.__language_code = '{{ LANGUAGE_CODE }}';
 </script>
-
 {% if not settings.GRAPPELLI_INSTALLED %}
 <script src="{% static "mezzanine/js/"|add:settings.JQUERY_FILENAME %}"></script>
 {% endif %}
diff --git a/app/templates/core/admin/base_site.html b/app/templates/core/admin/base_site.html
new file mode 100644 (file)
index 0000000..cc5649e
--- /dev/null
@@ -0,0 +1,77 @@
+{% extends "admin/base.html" %}
+{% load mezzanine_tags i18n staticfiles %}
+
+{% block title %}{{ title }} | Mezzanine{% endblock %}
+
+{% block extrahead %}
+<link rel="stylesheet" href="{% static "mezzanine/css/admin/global.css" %}">
+<style>
+    /* These are set in PageAdmin's view methods, and mezzanine.utils.admin.SingletonAdmin */
+    {% if hide_delete_link or singleton %}.submit-row .deletelink {display:none !important;}{% endif %}
+    {% if hide_slug_field %}.slug {display:none !important;}{% endif %}
+    {% if singleton %}.change-view-save-another {display:none !important;}{% endif %}
+</style>
+<script>
+    {% url "static_proxy" as static_proxy_url %}
+    {% url "fb_browse" as fb_browse_url %}
+    {% url "displayable_links_js" as link_list_url %}
+    {% url "admin:index" as admin_index_url %}
+    {% get_current_language as LANGUAGE_CODE %}
+    window.__home_link = '<a href="{% url "home" %}">{% trans "View site" %}</a>';
+    window.__csrf_token = '{{ csrf_token }}';
+    window.__admin_keywords_submit_url = '{% url "admin_keywords_submit" %}';
+    window.__filebrowser_url = '{{ fb_browse_url }}';
+    window.__link_list_url = '{{ link_list_url }}';
+    window.__tinymce_css = '{% static "mezzanine/css/tinymce.css" %}';
+    window.__admin_url = '{{ admin_index_url }}';
+    window.__static_proxy = '{{ static_proxy_url }}';
+    window.__admin_media_prefix__ = '{% static "admin" %}/';
+    window.__grappelli_installed = {{ settings.GRAPPELLI_INSTALLED|lower }};
+    window.__admin_menu_collapsed = {{ settings.ADMIN_MENU_COLLAPSED|lower }};
+    window.__language_code = '{{ LANGUAGE_CODE }}';
+</script>
+
+{% if not settings.GRAPPELLI_INSTALLED %}
+<script src="{% static "mezzanine/js/"|add:settings.JQUERY_FILENAME %}"></script>
+{% endif %}
+
+<script>
+jQuery(function($) {
+    $('.admin-title').click(function() {location = window.__admin_url;});
+    // This line can be removed after a decent amount of time has passed since
+    // https://github.com/stephenmcd/grappelli-safe/pull/56/files occurring.
+    $("#id_sitepermissions-__prefix__-sites").parent().parent().parent().remove();
+});
+</script>
+
+{% endblock %}
+
+{% block rtl_styles %}
+{{ block.super }}
+<link rel="stylesheet" type="text/css" href="{% static "mezzanine/css/admin/rtl.css" %}" />
+{% endblock %}
+
+{% block before_content %}
+{% if user.is_staff and not is_popup and not request.GET.pop %}
+{% admin_dropdown_menu %}
+{% endif %}
+{% endblock %}
+
+{% block footer %}
+{% if form.this_is_the_login_form %}
+    <script src="{% static "mezzanine/js/admin/login.js" %}"></script>
+{% else %}
+    {% if user.is_staff %}
+        {% if not is_popup and not request.GET.pop %}
+        <link rel="stylesheet" href="{% static "mezzanine/chosen/chosen.css" %}">
+        <!--<script src="{% static "mezzanine/chosen/chosen-0.9.12.jquery.js" %}"></script>-->
+        <script src="{% static "mezzanine/js/admin/navigation.js" %}"></script>
+
+        {% endif %}
+        <script src="{% static "mezzanine/js/admin/ajax_csrf.js" %}"></script>
+        {% if settings.GRAPPELLI_INSTALLED %}
+        <script src="{% static "mezzanine/js/admin/collapse_backport.js" %}"></script>
+        {% endif %}
+    {% endif %}
+{% endif %}
+{% endblock %}
index fe192a9e65baca0a2e3e59f1ca26e27af044116f..7cfda83e55976637fbf2e3886031a2fab5db1cb5 100644 (file)
@@ -1,7 +1,7 @@
 {% load mezzanine_tags i18n staticfiles %}
 
 {% compress js %}
-    <script src="{% static "vendors/jquery/dist/jquery.min.js" %}"></script>
+    <!--<script src="{% static "vendors/jquery/dist/jquery.min.js" %}"></script>-->
     <script src="{% static "vendors/overflow.js/js/overflow.js" %}"></script>
     <script src="{% static "vendors/sticky-kit/jquery.sticky-kit.js" %}"></script>
     <script src="{% static "vendors/jquery-throttle-debounce/jquery.ba-throttle-debounce.js" %}"></script>
index a2f808ed35f0758702342032e7c7441c834a0e6d..ace5a184559b313d61b63f7cb02d0c5ba3ec034e 100644 (file)
@@ -1,4 +1,5 @@
 -e git+https://github.com/yomguy/mezzanine-agenda.git#egg=mezzanine-agenda-0.2.2
 -e git+https://github.com/stephenmcd/mezzanine.git@master#egg=mezzanine-4.1-master
 -e git+https://github.com/stephenmcd/grappelli-safe.git@dynamic_stacked#egg=grappelli-safe-0.4.2
+-e git+https://github.com/yourlabs/django-autocomplete-light.git#egg=django-autocomplete-light
 #https://forge.ircam.fr/p/django-eve/source/download/dev/
index 719302e3550f16f852c195c0d93344a3e978ef62..080247cda17ed84719479dcaa798c5a47a9d60c6 100644 (file)
@@ -12,4 +12,3 @@ django-bower
 django-debug-toolbar
 django-extensions
 django-countries
-django-orderable