Wpis z mikrobloga

Napisałem sobie taki oto django-template-filter:

donations|sort_by_keys:'date,-value'
Mając dane:

donations = [

    {

        date: 



'29-07-2014'


,

        value: 150,

    },

    {

        date: 



'07-10-2014'


,

        value: 450,

    },

    {

        date: 



'29-07-2014'


,

        value: 500,

    },

]

za pomocą wywołania powyższego wywołania, powinienem otrzymać:

[

    {

        date: 



'29-07-2014'


,

        value: 500,

    },

    {

        date: 



'29-07-2014'


,

        value: 150,

    },

    {

        date: 



'07-10-2014'


,

        value: 450,

    },

]

Moja implementacja:

@register.filter


def
```**```
 sort_by_keys(value, keys):

    _list = 
```**```
list
```**```
(value)

``````

    
```**```
def
```**```
 compare(item1, item2):

        
```**```
for
```**```
 key in item1.__keys_for_sort.split(
```_```
','
```_```
):

``````

            
```**```
if
```**```
 key.startswith(
```_```
'-'
```_```
):

                key = key.replace(
```_```
'-'
```_```

```_```
''
```_```
)

``````

                
```**```
if
```**```
 
```**```
getattr
```**```
(item1, key) > 
```**```
getattr
```**```
(item2, key):

                    
```**```
return
```**```
 -1

                
```**```
elif
```**```
 
```**```
getattr
```**```
(item1, key) < 
```**```
getattr
```**```
(item2, key):

                    
```**```
return
```**```
 1

            
```**```
else
```**```
:

                
```**```
if
```**```
 
```**```
getattr
```**```
(item1, key) < 
```**```
getattr
```**```
(item2, key):

                    
```**```
return
```**```
 -1

                
```**```
elif
```**```
 
```**```
getattr
```**```
(item1, key) > 
```**```
getattr
```**```
(item2, key):

                    
```**```
return
```**```
 1

``````

        
```**```
return
```**```
 0

``````

    
```**```
for
```**```
 item in _list:

        
```**```
setattr
```**```
(item, 
```_```
'__keys_for_sort'
```_```
, keys)

``````

    _list = 
```**```
sorted
```**```
(_list, 
```**```
cmp
```**```
=compare)

``````

    
```**```
for
```**```
 item in _list:

        
```**```
delattr
```**```
(item, 
```_```
'__keys_for_sort'
```_```
)

``````

    
```**```
return
```**```
 _list

```Niestety bardzo mi się nie podoba wstrzykiwanie atrybutu ```
__keys_for_sort

, by móc tych kluczy użyć wewnątrz comparatora. Macie jakiś pomysl, jak napisać to lepiej?

#codereview #django
  • 17
  • Odpowiedz
  • Otrzymuj powiadomienia
    o nowych komentarzach

@noisy: a co za problem użyć go kilka razy? :)

{{ value|dictsort:"name1"|dictsort:"name2" }}
tak samo masz poniżej dictsortreversed, więc w twoim przypadku kod wyglądałby tak:

donations|dictsort:'date'|dictsortreversed:'value'
  • Odpowiedz
@miszczu_blady: no własnie jest problem... przeanalizuj przypadek danych jakie dostarczyłem.

Gdyby mnie takie rozwiązanie interesowało, to bym wcześniej napisał filtr (bo owszem, tego co napisałeś, to nie znałem, więc dzięki :) ).. mniej więcej takiej postaci:

def sort_by_keys(value,
  • Odpowiedz
@noisy: No nie wiem. Zakładając, że chcesz mieć posortowanią listę najpierw według daty (od najstarszych wpisów do najmłodszych), a następnie według value (od największej wartości do najmniejszej) to według mne takie użycie będzie równoznaczne z działaniem Twojego filtra:

{{ donations|dictsortreversed:'value'|dictsort:'date' }}
  • Odpowiedz
@noisy: chodziło, mi o to, że nie analizowałem tego w jakiej kolejności Ty to chciałeś mieć posortowane. wiedziałem, że coś takiego jest możliwe, ale dopiero po rozpisaniu w shellu zorientowałem się, że ma być na odwrót. nieważne, zanim zaczniesz pisać kolejne nowe filtry to sprawdź dokumentację :P
  • Odpowiedz