diff --git a/adminsortable/admin.py b/adminsortable/admin.py
index f80064a..b389546 100755
--- a/adminsortable/admin.py
+++ b/adminsortable/admin.py
@@ -53,13 +53,18 @@ class SortableAdmin(ModelAdmin):
has_perm = request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())
objects = self.model.objects.all()
- """
- Determine if we need to regroup objects relative to a foreign key specified on the
- model class that is extending Sortable.
- """
+ #Determine if we need to regroup objects relative to a foreign key specified on the
+ # model class that is extending Sortable.
sortable_by = getattr(self.model, 'sortable_by', None)
if sortable_by:
- sortable_by_class, sortable_by_expression = sortable_by()
+ #backwards compatibility for < 1.1.1, where sortable_by was a classmethod instead of a property
+ try:
+ sortable_by_class, sortable_by_expression = sortable_by()
+ except ValueError:
+ sortable_by_class = self.model.sortable_by
+ sortable_by_expression = sortable_by_class.__name__.lower()
+
+ print sortable_by_expression
sortable_by_class_display_name = sortable_by_class._meta.verbose_name_plural
sortable_by_class_is_sortable = sortable_by_class.is_sortable()
else:
diff --git a/adminsortable/models.py b/adminsortable/models.py
index 0d74262..af299de 100755
--- a/adminsortable/models.py
+++ b/adminsortable/models.py
@@ -14,8 +14,12 @@ class Sortable(models.Model):
`model_type_id` returns the ContentType.id for the Model that inherits Sortable
`save` the override of save increments the last/highest value of order by 1
+
+ Override `sortable_by` method to make your model be sortable by a foreign key field.
+ Set `sortable_by` to the class specified in the foreign key relationship.
"""
order = models.PositiveIntegerField(editable=False, default=1, db_index=True)
+ sortable_by = None
class Meta:
abstract = True
diff --git a/adminsortable/templates/adminsortable/change_list.html b/adminsortable/templates/adminsortable/change_list.html
index f5e7562..9d85464 100755
--- a/adminsortable/templates/adminsortable/change_list.html
+++ b/adminsortable/templates/adminsortable/change_list.html
@@ -55,7 +55,7 @@
{% if objects %}
{% if group_expression %}
- {% render_nested_sortable_objects objects group_expression %}
+ {% render_nested_sortable_objects objects group_expression %}
{% else %}
{% render_sortable_objects objects %}
{% endif %}
diff --git a/adminsortable/templatetags/django_template_additions.py b/adminsortable/templatetags/django_template_additions.py
index 252b2e8..4de7630 100755
--- a/adminsortable/templatetags/django_template_additions.py
+++ b/adminsortable/templatetags/django_template_additions.py
@@ -69,7 +69,7 @@ def dynamic_regroup(parser, token):
"""
expression = lastbits_reversed[2][::-1]
var_name = lastbits_reversed[0][::-1]
-
+ print expression
"""
We also need to hand the parser to the node in order to convert the value
for `expression` to a FilterExpression.
diff --git a/sample_project/adminsortable.sqlite b/sample_project/adminsortable.sqlite
index 5f71f74..df95757 100755
Binary files a/sample_project/adminsortable.sqlite and b/sample_project/adminsortable.sqlite differ
diff --git a/sample_project/app/admin.py b/sample_project/app/admin.py
index a1eb445..f365aab 100755
--- a/sample_project/app/admin.py
+++ b/sample_project/app/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin
from adminsortable.admin import SortableAdmin, SortableTabularInline, SortableStackedInline
-from app.models import Category, Project, Credit, Note
+from app.models import Category, Project, Credit, Note, Sample
admin.site.register(Category, SortableAdmin)
@@ -20,3 +20,4 @@ class ProjectAdmin(SortableAdmin):
list_display = ['__unicode__', 'category']
admin.site.register(Project, ProjectAdmin)
+admin.site.register(Sample, SortableAdmin)
diff --git a/sample_project/app/migrations/0003_add_sample.py b/sample_project/app/migrations/0003_add_sample.py
new file mode 100644
index 0000000..f683706
--- /dev/null
+++ b/sample_project/app/migrations/0003_add_sample.py
@@ -0,0 +1,68 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding model 'Sample'
+ db.create_table('app_sample', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=1, db_index=True)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=50)),
+ ('category', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['app.Category'])),
+ ('description', self.gf('django.db.models.fields.TextField')()),
+ ))
+ db.send_create_signal('app', ['Sample'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'Sample'
+ db.delete_table('app_sample')
+
+
+ models = {
+ 'app.category': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Category'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'app.credit': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Credit'},
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
+ 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Project']"})
+ },
+ 'app.note': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Note'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
+ 'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Project']"}),
+ 'text': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'app.project': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Project'},
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Category']"}),
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'app.sample': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Sample'},
+ 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Category']"}),
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ }
+ }
+
+ complete_apps = ['app']
diff --git a/sample_project/app/models.py b/sample_project/app/models.py
index caba787..2e8aab0 100755
--- a/sample_project/app/models.py
+++ b/sample_project/app/models.py
@@ -29,13 +29,28 @@ class Project(SimpleModel, Sortable):
class Meta(Sortable.Meta):
pass
- @classmethod
- def sortable_by(cls):
- return Category, 'category'
+# @classmethod
+# def sortable_by(cls):
+# return Category, 'category'
category = models.ForeignKey(Category)
description = models.TextField()
+ sortable_by = Category
+
+
+#a model that is sortable relative to a foreign key that is also sortable
+class Sample(SimpleModel, Sortable):
+ class Meta(Sortable.Meta):
+ pass
+
+ category = models.ForeignKey(Category)
+ description = models.TextField()
+
+ #field to define which foreign key the model is sortable by.
+ #works with versions > 1.1.1
+ sortable_by = Category
+
#registered as a tabular inline on project
class Credit(Sortable):
diff --git a/sample_project/app/tests.py b/sample_project/app/tests.py
index 3eb1677..13a59ad 100755
--- a/sample_project/app/tests.py
+++ b/sample_project/app/tests.py
@@ -1,12 +1,9 @@
import httplib
import json
-from django.contrib.auth.forms import authenticate, UserCreationForm
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
-from django.middleware import csrf
from django.db import models
-from django.template.defaultfilters import urlencode
from django.test import TestCase
from django.test.client import Client, RequestFactory
@@ -83,6 +80,9 @@ class SortableTestCase(TestCase):
def get_category_indexes(self, *categories):
return {'indexes' : ','.join([str(c.id) for c in categories])}
+ def test_sortable_by_backwards_compatibility(self):
+ pass
+
def test_adminsortable_changelist_templates(self):
logged_in = self.client.login(username=self.user.username, password=self.user_raw_password)
self.assertTrue(logged_in, 'User is not logged in')
diff --git a/sample_project/settings.py b/sample_project/settings.py
index c16655e..0309bf8 100755
--- a/sample_project/settings.py
+++ b/sample_project/settings.py
@@ -102,7 +102,6 @@ MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
- 'debug_toolbar.middleware.DebugToolbarMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (