django-admin-sortable/adminsortable/models.py
Brandon Taylor 014f6d1660 Added support for queryset() overrides on admin classes and inline admin classes.
Updated version to 1.4.5.
Updated README with explanation of requirements for overriding queryset() on inline models.
Added extra models to sample project to demonstrate sortable models with custom querysets.
Improved JavaScript of sortables to be more efficient with better comparison checking.
Fixed highlighting of stacked inlines on sort finish.
2013-04-27 22:58:02 -04:00

79 lines
2.4 KiB
Python

from django.contrib.contenttypes.models import ContentType
from django.db import models
from adminsortable.fields import SortableForeignKey
class MultipleSortableForeignKeyException(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class Sortable(models.Model):
"""
Unfortunately, Django doesn't support using more than one AutoField
in a model or this class could be simplified.
`is_sortable` determines whether or not the Model is sortable by
determining if the last value of `order` is greater than the default
of 1, which should be present if there is only one object.
`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
"""
order = models.PositiveIntegerField(editable=False, default=1,
db_index=True)
is_sortable = False
# legacy support
sortable_by = None
class Meta:
abstract = True
ordering = ['order']
# @classmethod
# def determine_if_sortable(cls):
# try:
# max_order = cls.objects.aggregate(
# models.Max('order'))['order__max']
# except (TypeError, IndexError):
# max_order = 0
# if max_order > 1:
# cls.is_sortable = True
# else:
# cls.is_sortable = False
@classmethod
def model_type_id(cls):
return ContentType.objects.get_for_model(cls).id
def __init__(self, *args, **kwargs):
super(Sortable, self).__init__(*args, **kwargs)
# Validate that model only contains at most one SortableForeignKey
sortable_foreign_keys = []
for field in self._meta.fields:
if isinstance(field, SortableForeignKey):
sortable_foreign_keys.append(field)
if len(sortable_foreign_keys) > 1:
raise MultipleSortableForeignKeyException(
u'%s may only have one SortableForeignKey' % self)
def save(self, *args, **kwargs):
if not self.id:
try:
self.order = self.__class__.objects.aggregate(
models.Max('order'))['order__max'] + 1
except (TypeError, IndexError):
pass
super(Sortable, self).save(*args, **kwargs)