]> git.parisson.com Git - mezzo.git/commitdiff
Media : ordering by date
authorEmilie <zawadzki@ircam.fr>
Fri, 30 Sep 2016 17:08:25 +0000 (19:08 +0200)
committerEmilie <zawadzki@ircam.fr>
Fri, 30 Sep 2016 17:08:25 +0000 (19:08 +0200)
app/organization/core/templatetags/organization_tags.py
app/organization/core/utils.py [deleted file]
app/organization/media/migrations/0005_auto_20160930_1849.py [new file with mode: 0644]
app/organization/media/models.py
app/organization/media/views.py
app/templates/media/media_list.html

index fc8ba6b43cd63903648fd618cd7edbc6afca65c5..b75bf00a008aba259e7bdd8c271de9cb22961176 100644 (file)
@@ -113,3 +113,7 @@ def in_category(objects, category):
 @register.filter
 def sub_topics(topic):
     return ProjectTopic.objects.filter(parent=topic)
+
+@register.filter
+def classname(obj):
+    return obj.__class__.__name__
diff --git a/app/organization/core/utils.py b/app/organization/core/utils.py
deleted file mode 100644 (file)
index e13a9fe..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-from itertools import chain, dropwhile
-from operator import mul, attrgetter, __not__
-
-from django.db.models.query import REPR_OUTPUT_SIZE, EmptyQuerySet
-
-# Django Snippets
-# https://djangosnippets.org/snippets/1933/
-
-def mul_it(it1, it2):
-    '''
-    Element-wise iterables multiplications.
-    '''
-    assert len(it1) == len(it2),\
-           "Can not element-wise multiply iterables of different length."
-    return map(mul, it1, it2)
-
-
-def chain_sing(*iterables_or_items):
-    '''
-    As itertools.chain except that if an argument is not iterable then chain it
-    as a singleton.
-    '''
-    for iter_or_item in iterables_or_items:
-        if hasattr(iter_or_item, '__iter__'):
-            for item in iter_or_item:
-                yield item
-        else:
-            yield iter_or_item
-
-
-class IableSequence(object):
-    '''
-    Wrapper for sequence of iterable and indexable by non-negative integers
-    objects. That is a sequence of objects which implement __iter__, __len__ and
-    __getitem__ for slices, ints and longs.
-
-    Note: not a Django-specific class.
-    '''
-    def __init__(self, *args, **kwargs):
-        self.iables = args # wrapped sequence
-        self._len = None # length cache
-        self._collapsed = [] # collapsed elements cache
-
-    def __len__(self):
-        if not self._len:
-            self._len = sum(len(iable) for iable in self.iables)
-        return self._len
-
-
-    def __iter__(self):
-        return chain(*self.iables)
-
-    def __nonzero__(self):
-        try:
-            iter(self).__next__()
-        except StopIteration:
-            return False
-        return True
-
-
-    def _collect(self, start=0, stop=None, step=1):
-        if not stop:
-            stop = len(self)
-        sub_iables = []
-        # collect sub sets
-        it = self.iables.__iter__()
-        try:
-            while stop>start:
-                i = it.__next__()
-                i_len = len(i)
-                if i_len > start:
-                    # no problem with 'stop' being too big
-                    sub_iables.append(i[start:stop:step])
-                start = max(0, start-i_len)
-                stop -= i_len
-        except StopIteration:
-            pass
-        return sub_iables
-
-    def __getitem__(self, key):
-        '''
-        Preserves wrapped indexable sequences.
-        Does not support negative indices.
-        '''
-        # params validation
-        if not isinstance(key, (slice, int, long)):
-            raise TypeError
-        assert ((not isinstance(key, slice) and (key >= 0))
-                or (isinstance(key, slice) and (key.start is None or key.start >= 0)
-                    and (key.stop is None or key.stop >= 0))), \
-                "Negative indexing is not supported."
-        # initialization
-        if isinstance(key, slice):
-            start, stop, step = key.indices(len(self))
-            ret_item=False
-        else: # isinstance(key, (int,long))
-            start, stop, step = key, key+1, 1
-            ret_item=True
-        # collect sub sets
-        ret_iables = self._collect(start, stop, step)
-        # return the simplest possible answer
-        if not len(ret_iables):
-            if ret_item:
-                raise IndexError("'%s' index out of range" % self.__class__.__name__)
-            return ()
-        if ret_item:
-            # we have exactly one query set with exactly one item
-            assert len(ret_iables) == 1 and len(ret_iables[0]) == 1
-            return ret_iables[0][0]
-        # otherwise we have more then one item in at least one query set
-        if len(ret_iables) == 1:
-            return ret_iables[0]
-        # Note: this can't be self.__class__ instead of IableSequence; exemplary
-        # cause is that indexing over query sets returns lists so we can not
-        # return QuerySetSequence by default. Some type checking enhancement can
-        # be implemented in subclasses.
-        return IableSequence(*ret_iables)
-
-
-    def collapse(self, stop=None):
-        '''
-        Collapses sequence into a list.
-
-        Try to do it effectively with caching.
-        '''
-        if not stop:
-            stop = len(self)
-        # if we already calculated sufficient collapse then return it
-        if len(self._collapsed) >= stop:
-            return self._collapsed[:stop]
-        # otherwise collapse only the missing part
-        items = self._collapsed
-        sub_iables = self._collect(len(self._collapsed), stop)
-        for sub_iable in sub_iables:
-            items+=sub_iable
-        # cache new collapsed items
-        self._collapsed = items
-        return self._collapsed
-
-    def __repr__(self):
-        # get +1 element for the truncation msg if applicable
-        items = self.collapse(stop=REPR_OUTPUT_SIZE+1)
-        if len(items) > REPR_OUTPUT_SIZE:
-            items[-1] = "...(remaining elements truncated)..."
-        return repr(items)
-
-# http://stackoverflow.com/questions/1516249/python-list-sorting-with-multiple-attributes-and-mixed-order
-class QuerySetSequence(IableSequence):
-    '''
-    Wrapper for the query sets sequence without the restriction on the identity
-    of the base models.
-    '''
-    def count(self):
-        if not self._len:
-            self._len = sum(qs.count() for qs in self.iables)
-        return self._len
-
-    def __len__(self):
-        # override: use DB effective count's instead of len()
-        return self.count()
-
-    def order_by(self, *field_names):
-        '''
-        Returns a list of the QuerySetSequence items with the ordering changed.
-        '''
-        # construct a comparator function based on the field names prefixes
-        reverses = [1] * len(field_names)
-        field_names = list(field_names)
-        for i in range(len(field_names)):
-            field_name = field_names[i]
-            if field_name[0] == '-':
-                reverses[i] = -1
-                field_names[i] = field_name[1:]
-        # wanna iterable and attrgetter returns single item if 1 arg supplied
-        fields_getter = lambda i: chain_sing(attrgetter(*field_names)(i))
-        print("************************")
-        print(fields_getter)
-        print("************************")
-        # comparator gets the first non-zero value of the field comparison
-        # results taking into account reverse order for fields prefixed with '-'
-        comparator = lambda i1, i2:\
-            dropwhile(__not__,
-              mul_it(map(key, fields_getter(i1), fields_getter(i2)), reverses)
-            ).__next__()
-
-        # return new sorted list
-        return sorted(self.collapse(), key=fields_getter)
-
-    def filter(self, *args, **kwargs):
-        """
-        Returns a new QuerySetSequence or instance with the args ANDed to the
-        existing set.
-
-        QuerySetSequence is simplified thus result actually can be one of:
-        QuerySetSequence, QuerySet, EmptyQuerySet.
-        """
-        return self._filter_or_exclude(False, *args, **kwargs)
-
-    def exclude(self, *args, **kwargs):
-        """
-        Returns a new QuerySetSequence instance with NOT (args) ANDed to the
-        existing set.
-
-        QuerySetSequence is simplified thus result actually can be one of:
-        QuerySetSequence, QuerySet, EmptyQuerySet.
-        """
-        return self._filter_or_exclude(True, *args, **kwargs)
-
-    def _simplify(self, qss=None):
-        '''
-        Returns QuerySetSequence, QuerySet or EmptyQuerySet depending on the
-        contents of items, i.e. at least two non empty QuerySets, exactly one
-        non empty QuerySet and all empty QuerySets respectively.
-
-        Does not modify original QuerySetSequence.
-        '''
-        not_empty_qss = filter(None, qss if qss else self.iables)
-        if not len(not_empty_qss):
-            return EmptyQuerySet()
-        if len(not_empty_qss) == 1:
-            return not_empty_qss[0]
-        return QuerySetSequence(*not_empty_qss)
-
-    def _filter_or_exclude(self, negate, *args, **kwargs):
-        '''
-        Maps _filter_or_exclude over QuerySet items and simplifies the result.
-        '''
-        # each Query set is cloned separately
-        return self._simplify(*map(lambda qs:
-            qs._filter_or_exclude(negate, *args, **kwargs), self.iables))
-
-    def exists(self):
-        for qs in self.iables:
-            if qs.exists():
-                return True
-        return False
-
-
-def cmp_to_key(mycmp):
-    'Convert a cmp= function into a key= function'
-    class K(object):
-        def __init__(self, obj, *args):
-            self.obj = obj
-        def __lt__(self, other):
-            return mycmp(self.obj, other.obj) < 0
-        def __gt__(self, other):
-            return mycmp(self.obj, other.obj) > 0
-        def __eq__(self, other):
-            return mycmp(self.obj, other.obj) == 0
-        def __le__(self, other):
-            return mycmp(self.obj, other.obj) <= 0
-        def __ge__(self, other):
-            return mycmp(self.obj, other.obj) >= 0
-        def __ne__(self, other):
-            return mycmp(self.obj, other.obj) != 0
-    return K
diff --git a/app/organization/media/migrations/0005_auto_20160930_1849.py b/app/organization/media/migrations/0005_auto_20160930_1849.py
new file mode 100644 (file)
index 0000000..2aa0ec0
--- /dev/null
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.7 on 2016-09-30 16:49
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('organization-media', '0004_auto_20160930_1039'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='audio',
+            options={'ordering': ('-created_at',), 'verbose_name': 'audio'},
+        ),
+        migrations.AlterModelOptions(
+            name='video',
+            options={'ordering': ('-created_at',), 'verbose_name': 'video'},
+        ),
+    ]
index cfa70c4f9f1ae8979b7863ccb90b856567e986db..54f32841058e2ddd696b98e2cf18974082472f52 100644 (file)
@@ -62,6 +62,7 @@ class Audio(Media):
 
     class Meta:
         verbose_name = _('audio')
+        ordering = ('-created_at',)
 
     def get_absolute_url(self):
         return reverse("festival-audio-detail", kwargs={"slug": self.slug})
@@ -76,6 +77,7 @@ class Video(Media):
 
     class Meta:
         verbose_name = _('video')
+        ordering = ('-created_at',)
 
     def get_absolute_url(self):
         return reverse("festival-video-detail", kwargs={"slug": self.slug})
index 525895f81e121b466664f12769fa682a849560ee..044c90d5939a690b700efff6d25e7492332d5e6a 100644 (file)
@@ -51,11 +51,10 @@ class MediaListView(ListView):
     context_object_name = 'media'
 
     def get_queryset(self):
-
         audios = Audio.objects.all()
         videos = Video.objects.all()
-        qsseq = QuerySetSequence(audios, videos)
-        qsseq.order_by('created_at',)
-        print("----------------------------------")
-        print(len(qsseq))
-        return qsseq
+        media_list = [video for video in videos]
+        media_list += [audio for audio in audios]
+        media_list.sort(key=lambda x: x.created_at, reverse=True)
+
+        return media_list
index dfa4eff1f556d65f12f0deec590a69a4484b899e..41526d7fa9790c249169172b696f1430c3f9874a 100644 (file)
@@ -29,7 +29,7 @@
 {% block page_content %}
 
 {% for m in media %}
-    {{ m.get_content_model }} : {{ m.created_at }} : {{ m.title }}
+    {{ m|classname }} : {{ m.created_at }} : {{ m.title }}
     <br>
 {% endfor %}