diff --git a/README.txt b/README.txt
index b833068..f00ffe0 100644
--- a/README.txt
+++ b/README.txt
@@ -1,3 +1,13 @@
+Changes to this fork
+----------------------------
+
+{% autosort %} can sort on custom fields (properties) in addition to regular fields
+
+{% anchor %} can specify a default sort order as a third parameter.
+
+
{% anchor first_name Name asc %} |
+{% anchor first_name Name desc %} |
+
How to use django-sorting
----------------------------
diff --git a/django_sorting/templatetags/sorting_tags.py b/django_sorting/templatetags/sorting_tags.py
index 7cdeb42..129482d 100644
--- a/django_sorting/templatetags/sorting_tags.py
+++ b/django_sorting/templatetags/sorting_tags.py
@@ -1,6 +1,7 @@
from django import template
from django.http import Http404
from django.conf import settings
+from django.core.exceptions import FieldError
register = template.Library()
@@ -17,17 +18,24 @@
def anchor(parser, token):
"""
- Parses a tag that's supposed to be in this format: {% anchor field title %}
+ Parses a tag that's supposed to be in this format: {% anchor field title sortdir %}
"""
bits = [b.strip('"\'') for b in token.split_contents()]
+
if len(bits) < 2:
raise TemplateSyntaxError, "anchor tag takes at least 1 argument"
- try:
+
+ field = bits[1].strip()
+ title = field.capitalize()
+ sortdir = ''
+
+ if len(bits) >= 3:
title = bits[2]
- except IndexError:
- title = bits[1].capitalize()
- return SortAnchorNode(bits[1].strip(), title.strip())
-
+
+ if len(bits) == 4:
+ sortdir = bits[3]
+
+ return SortAnchorNode(field, title, sortdir)
class SortAnchorNode(template.Node):
"""
@@ -37,13 +45,14 @@ class SortAnchorNode(template.Node):
currently being sorted on.
Eg.
- {% anchor name Name %} generates
- Name
+ {% anchor name Name asc %} generates
+ Name
"""
- def __init__(self, field, title):
+ def __init__(self, field, title, sortdir):
self.field = field
self.title = title
+ self.sortdir = sortdir
def render(self, context):
request = context['request']
@@ -53,20 +62,28 @@ def render(self, context):
del getvars['sort']
else:
sortby = ''
+
if 'dir' in getvars:
sortdir = getvars['dir']
del getvars['dir']
else:
- sortdir = ''
+ sortdir = self.sortdir
+
if sortby == self.field:
getvars['dir'] = sort_directions[sortdir]['inverse']
icon = sort_directions[sortdir]['icon']
else:
+ # If we're not on the current field, use the default sortdir
+ # rather than the order
+ if self.sortdir:
+ getvars['dir'] = self.sortdir
icon = ''
+
if len(getvars.keys()) > 0:
urlappend = "&%s" % getvars.urlencode()
else:
urlappend = ''
+
if icon:
title = "%s %s" % (self.title, icon)
else:
@@ -96,7 +113,20 @@ def render(self, context):
order_by = context['request'].field
if len(order_by) > 1:
try:
- context[key] = value.order_by(order_by)
+ try:
+ val = list(value.order_by(order_by))
+ context[key] = val
+ except:
+ ## Support for sorting on properties
+
+ # Split off reverse sort
+ reverse = False
+ if order_by.startswith("-"):
+ order_by = order_by[1:]
+ reverse = True
+
+ context[key] = sorted(value, key=lambda v: getattr(v, order_by), reverse=reverse)
+
except template.TemplateSyntaxError:
if INVALID_FIELD_RAISES_404:
raise Http404('Invalid field sorting. If DEBUG were set to ' +