]> git.0d.be Git - django-panik-combo.git/commitdiff
replace django-select2 dependency by own code
authorFrédéric Péters <fpeters@0d.be>
Sat, 21 Nov 2020 08:51:21 +0000 (09:51 +0100)
committerFrédéric Péters <fpeters@0d.be>
Sat, 21 Nov 2020 08:51:21 +0000 (09:51 +0100)
panikombo/forms.py
panikombo/templates/panikombo/select2.html [new file with mode: 0644]
panikombo/urls.py [new file with mode: 0644]
panikombo/views.py

index d51d1ce4f486f3defc25e55ad5d8fa42abdb4ece..c84dbfab1607522720c1498c357099565b31d51a 100644 (file)
@@ -1,24 +1,37 @@
 import json
 
 from django import forms
-from django_select2.forms import HeavySelect2Widget
+from django.forms.widgets import Widget
 from taggit.forms import TagWidget
 
 from emissions.models import SoundFile, Episode
 
 from .models import (SoundCell, EpisodeCell, EpisodeAutoSelectionCell,
         NewsItemAutoSelectionCell)
-from .views import soundfiles, episodes
 
-class SoundFileWidget(HeavySelect2Widget):
-    def render_texts(self, selected_choices, choices):
-        queryset = SoundFile.objects.filter(id__in=selected_choices)
-        def fmt(soundfile):
-            return '%s - %s - %s' % (soundfile.episode.emission.title,
+
+class BaseSelect2Widget(Widget):
+    template_name = "panikombo/select2.html"
+
+    def get_context(self, name, value, attrs):
+        context = super().get_context(name, value, attrs)
+        context['view_name'] = self.view_name
+        if value:
+            context['widget']['view_value'] = self.view_value(value)
+        return context
+
+
+class SoundFileWidget(BaseSelect2Widget):
+    view_name = 'panikombo-select2-soundfiles'
+
+    def view_value(self, value):
+        try:
+            soundfile = SoundFile.objects.get(id=value)
+        except SoundFile.DoesNotExist:
+            return 'missing sound %s' % value
+        return '%s - %s - %s' % (soundfile.episode.emission.title,
                     soundfile.episode.title,
                     soundfile.title or soundfile.id)
-        texts = [fmt(soundfile) for soundfile in queryset.select_related()]
-        return json.dumps(texts)
 
 
 class SoundCellForm(forms.ModelForm):
@@ -28,16 +41,18 @@ class SoundCellForm(forms.ModelForm):
 
     def __init__(self, *args, **kwargs):
         super(SoundCellForm, self).__init__(*args, **kwargs)
-        self.fields['soundfile'].widget = SoundFileWidget(data_view=soundfiles)
+        self.fields['soundfile'].widget = SoundFileWidget()
+
 
+class EpisodeWidget(BaseSelect2Widget):
+    view_name = 'panikombo-select2-episodes'
 
-class EpisodeWidget(HeavySelect2Widget):
-    def render_texts(self, selected_choices, choices):
-        queryset = Episode.objects.filter(id__in=selected_choices)
-        def fmt(episode):
-            return '%s - %s' % (episode.emission.title, episode.title)
-        texts = [fmt(episode) for episode in queryset.select_related()]
-        return json.dumps(texts)
+    def view_value(self, value):
+        try:
+            episode = Episode.objects.get(id=value)
+        except Episode.DoesNotExist:
+            return 'missing episode %s' % value
+        return '%s - %s' % (episode.emission.title, episode.title)
 
 
 class EpisodeCellForm(forms.ModelForm):
@@ -47,7 +62,7 @@ class EpisodeCellForm(forms.ModelForm):
 
     def __init__(self, *args, **kwargs):
         super(EpisodeCellForm, self).__init__(*args, **kwargs)
-        self.fields['episode'].widget = EpisodeWidget(data_view=episodes)
+        self.fields['episode'].widget = EpisodeWidget()
 
 
 class EpisodeAutoSelectionCellForm(forms.ModelForm):
diff --git a/panikombo/templates/panikombo/select2.html b/panikombo/templates/panikombo/select2.html
new file mode 100644 (file)
index 0000000..4137d9a
--- /dev/null
@@ -0,0 +1,24 @@
+<select style="width: 100%" name="{{ widget.name }}" {% include "django/forms/widgets/attrs.html" %}>
+{% if widget.value != None %}<option value="{{ widget.value }}">{{widget.view_value}}</option>{% endif %}
+</select>
+<script>
+$(function() {
+    var options = {
+      placeholder: '',
+      minimumInputLength: 3,
+      ajax: {
+        url: function() {
+          return "{% url view_name %}";
+        },
+        dataType: 'json',
+        data: function(params) {
+          var query = {
+            term: params.term,
+          }
+          return query;
+        },
+      },
+    };
+    $('select[name={{widget.name}}]').select2(options);
+})
+</script>
diff --git a/panikombo/urls.py b/panikombo/urls.py
new file mode 100644 (file)
index 0000000..90cf91e
--- /dev/null
@@ -0,0 +1,8 @@
+from django.conf.urls import url
+
+from . import views
+
+urlpatterns = [
+    url(r'^select2/episodes/$', views.episodes, name='panikombo-select2-episodes'),
+    url(r'^select2/soundfiles/$', views.soundfiles, name='panikombo-select2-soundfiles'),
+]
index faa454e1da73c2cf7322ba74efcdc57d06e69700..e2c2ac208633640392ae118dd09c14120ac3a414 100644 (file)
@@ -1,60 +1,61 @@
-from django.core.urlresolvers import reverse
+from django.contrib.auth.decorators import login_required
 from django.db.models import Q
-from django.http import Http404, JsonResponse
-from django.views.generic.edit import UpdateView
-import django_select2.views
+from django.http import JsonResponse
 
 from emissions.models import SoundFile, Episode
 
 
-class SoundFilesView(django_select2.views.AutoResponseView):
-    def get(self, request, *args, **kwargs):
-        terms = kwargs.get('term', request.GET.get('term', ''))
-        queryset = SoundFile.objects.all()
-        for term in terms.split():
-            queryset = queryset.filter(podcastable=True).filter(Q(title__icontains=term) |
-                    Q(episode__title__icontains=term) |
-                    Q(episode__emission__title__icontains=term))
-        def fmt(soundfile):
-            return '%s - %s - %s' % (soundfile.episode.emission.title,
-                    soundfile.episode.title,
-                    soundfile.title or soundfile.id)
-
-        return JsonResponse({
+@login_required
+def soundfiles(request, *args, **kwargs):
+    terms = kwargs.get('term', request.GET.get('term', ''))
+    queryset = SoundFile.objects.all()
+    for term in terms.split():
+        queryset = queryset.filter(podcastable=True).filter(
+            Q(title__icontains=term)
+            | Q(episode__title__icontains=term)
+            | Q(episode__emission__title__icontains=term)
+        )
+
+    def fmt(soundfile):
+        return '%s - %s - %s' % (
+            soundfile.episode.emission.title,
+            soundfile.episode.title,
+            soundfile.title or soundfile.id,
+        )
+
+    return JsonResponse(
+        {
             'results': [
                 {
                     'text': fmt(x),
                     'id': x.pk,
                 }
                 for x in queryset
-                ],
-            'more': False
-        })
+            ],
+            'more': False,
+        }
+    )
 
 
-soundfiles = SoundFilesView.as_view()
+@login_required
+def episodes(request, *args, **kwargs):
+    terms = kwargs.get('term', request.GET.get('term', ''))
+    queryset = Episode.objects.all()
+    for term in terms.split():
+        queryset = queryset.filter(Q(title__icontains=term) | Q(emission__title__icontains=term))
 
+    def fmt(episode):
+        return '%s - %s' % (episode.emission.title, episode.title)
 
-class EpisodesView(django_select2.views.AutoResponseView):
-    def get(self, request, *args, **kwargs):
-        terms = kwargs.get('term', request.GET.get('term', ''))
-        queryset = Episode.objects.all()
-        for term in terms.split():
-            queryset = queryset.filter(Q(title__icontains=term) |
-                    Q(emission__title__icontains=term))
-        def fmt(episode):
-            return '%s - %s' % (episode.emission.title, episode.title)
-
-        return JsonResponse({
+    return JsonResponse(
+        {
             'results': [
                 {
                     'text': fmt(x),
                     'id': x.pk,
                 }
                 for x in queryset
-                ],
-            'more': False
-        })
-
-
-episodes = EpisodesView.as_view()
+            ],
+            'more': False,
+        }
+    )