diff --git a/sample_project/app/models.py b/sample_project/app/models.py index bf8b563..c4c44dd 100644 --- a/sample_project/app/models.py +++ b/sample_project/app/models.py @@ -4,7 +4,7 @@ from django.db import models from django.utils.encoding import python_2_unicode_compatible from adminsortable.fields import SortableForeignKey -from adminsortable.models import Sortable +from adminsortable.models import Sortable, SortableMixin @python_2_unicode_compatible @@ -19,59 +19,65 @@ class SimpleModel(models.Model): # A model that is sortable -class Category(SimpleModel, Sortable): - class Meta(Sortable.Meta): - """ - Classes that inherit from Sortable must define an inner - Meta class that inherits from Sortable.Meta or ordering - won't work as expected - """ +class Category(SimpleModel, SortableMixin): + class Meta: verbose_name_plural = 'Categories' + ordering = ['order'] + + order = models.PositiveIntegerField(default=0, editable=False) # A model with an override of its queryset for admin @python_2_unicode_compatible -class Widget(SimpleModel, Sortable): - class Meta(Sortable.Meta): - pass +class Widget(SimpleModel, SortableMixin): + class Meta: + ordering = ['order'] def __str__(self): return self.title + order = models.PositiveIntegerField(default=0, editable=False) + # A model that is sortable relative to a foreign key that is also sortable # uses SortableForeignKey field. Works with versions 1.3+ -class Project(SimpleModel, Sortable): - class Meta(Sortable.Meta): - pass +class Project(SimpleModel, SortableMixin): + class Meta: + ordering = ['order'] category = SortableForeignKey(Category) description = models.TextField() + order = models.PositiveIntegerField(default=0, editable=False) + # Registered as a tabular inline on `Project` @python_2_unicode_compatible -class Credit(Sortable): - class Meta(Sortable.Meta): - pass +class Credit(SortableMixin): + class Meta: + ordering = ['order'] project = models.ForeignKey(Project) first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30) + order = models.PositiveIntegerField(default=0, editable=False) + def __str__(self): return '{0} {1}'.format(self.first_name, self.last_name) # Registered as a stacked inline on `Project` @python_2_unicode_compatible -class Note(Sortable): - class Meta(Sortable.Meta): - pass +class Note(SortableMixin): + class Meta: + ordering = ['order'] project = models.ForeignKey(Project) text = models.CharField(max_length=100) + order = models.PositiveIntegerField(default=0, editable=False) + def __str__(self): return self.text @@ -99,15 +105,17 @@ class NonSortableNote(models.Model): # A generic bound model @python_2_unicode_compatible -class GenericNote(SimpleModel, Sortable): +class GenericNote(SimpleModel, SortableMixin): content_type = models.ForeignKey(ContentType, verbose_name=u"Content type", related_name="generic_notes") object_id = models.PositiveIntegerField(u"Content id") content_object = generic.GenericForeignKey(ct_field='content_type', fk_field='object_id') - class Meta(Sortable.Meta): - pass + order = models.PositiveIntegerField(default=0, editable=False) + + class Meta: + ordering = ['order'] def __str__(self): return u'{0}: {1}'.format(self.title, self.content_object) @@ -115,25 +123,30 @@ class GenericNote(SimpleModel, Sortable): # An model registered as an inline that has a custom queryset @python_2_unicode_compatible -class Component(SimpleModel, Sortable): - class Meta(Sortable.Meta): - pass +class Component(SimpleModel, SortableMixin): + class Meta: + ordering = ['order'] widget = SortableForeignKey(Widget) + order = models.PositiveIntegerField(default=0, editable=False) + def __str__(self): return self.title @python_2_unicode_compatible -class Person(Sortable): - class Meta(Sortable.Meta): +class Person(SortableMixin): + class Meta: + ordering = ['order'] verbose_name_plural = 'People' first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) is_board_member = models.BooleanField('Board Member', default=False) + order = models.PositiveIntegerField(default=0, editable=False) + # Sorting Filters allow you to set up sub-sets of objects that need # to have independent sorting. They are listed in order, from left # to right in the sorting change list. You can use any standard @@ -158,26 +171,32 @@ class NonSortableCategory(SimpleModel): @python_2_unicode_compatible -class SortableCategoryWidget(SimpleModel, Sortable): - class Meta(Sortable.Meta): +class SortableCategoryWidget(SimpleModel, SortableMixin): + class Meta: + ordering = ['order'] verbose_name = 'Sortable Category Widget' verbose_name_plural = 'Sortable Category Widgets' non_sortable_category = SortableForeignKey(NonSortableCategory) + order = models.PositiveIntegerField(default=0, editable=False) + def __str__(self): return self.title @python_2_unicode_compatible -class SortableNonInlineCategory(SimpleModel, Sortable): +class SortableNonInlineCategory(SimpleModel, SortableMixin): """Example of a model that is sortable, but has a SortableForeignKey that is *not* sortable, and is also not defined as an inline of the SortableForeignKey field.""" non_sortable_category = SortableForeignKey(NonSortableCategory) - class Meta(Sortable.Meta): + order = models.PositiveIntegerField(default=0, editable=False) + + class Meta: + ordering = ['order'] verbose_name = 'Sortable Non-Inline Category' verbose_name_plural = 'Sortable Non-Inline Categories' diff --git a/sample_project/app/tests.py b/sample_project/app/tests.py index 69cd7ac..9d4501a 100644 --- a/sample_project/app/tests.py +++ b/sample_project/app/tests.py @@ -10,14 +10,19 @@ from django.db import models from django.test import TestCase from django.test.client import Client -from adminsortable.models import Sortable +from adminsortable.models import SortableMixin from adminsortable.utils import get_is_sortable from app.models import Category, Person, Project -class TestSortableModel(Sortable): +class TestSortableModel(SortableMixin): title = models.CharField(max_length=100) + order = models.PositiveIntegerField(default=0, editable=False) + + class Meta: + ordering = ['order'] + def __unicode__(self): return self.title @@ -110,7 +115,7 @@ class SortableTestCase(TestCase): self.assertEqual(response.status_code, httplib.OK, 'Admin sort request failed.') - #assert adminsortable change list templates are used + # assert adminsortable change list templates are used template_names = [t.name for t in response.templates] self.assertTrue('adminsortable/change_list.html' in template_names, 'adminsortable/change_list.html was not rendered') @@ -121,7 +126,7 @@ class SortableTestCase(TestCase): self.assertTrue(logged_in, 'User is not logged in') category1, category2, category3 = self.make_test_categories() - #make a normal POST + # make a normal POST response = self.client.post(self.get_sorting_url(), data=self.get_category_indexes(category1, category2, category3)) content = json.loads(response.content.decode(encoding='UTF-8'), @@ -134,10 +139,10 @@ class SortableTestCase(TestCase): password=self.user_raw_password) self.assertTrue(logged_in, 'User is not logged in') - #make categories + # make categories category1, category2, category3 = self.make_test_categories() - #make an Ajax POST + # make an Ajax POST response = self.client.post(self.get_sorting_url(), data=self.get_category_indexes(category3, category2, category1), HTTP_X_REQUESTED_WITH='XMLHttpRequest') @@ -146,7 +151,7 @@ class SortableTestCase(TestCase): self.assertTrue(content.get('objects_sorted'), 'Objects should have been sorted.') - #assert order is correct + # assert order is correct categories = Category.objects.all() cat1 = categories[0] cat2 = categories[1] diff --git a/sample_project/database/test_project.sqlite b/sample_project/database/test_project.sqlite index 77631b3..af8ac53 100644 Binary files a/sample_project/database/test_project.sqlite and b/sample_project/database/test_project.sqlite differ