from functools import total_ordering from django.core import checks from django.db import models from django.db.models import Min from django.utils.translation import gettext_lazy as _ @total_ordering class OrderableModel(models.Model): ordering = models.IntegerField("Kolejność", default=0) class Meta: abstract = True ordering = ["ordering"] def save(self, *args, **kwargs): if not self.ordering: min = self.__class__._default_manager.aggregate(m=Min("ordering"))[ "m"] self.ordering = (min or 0) - 10 super().save(*args, **kwargs) save.alters_data = True def __lt__(self, other): return ( self.ordering > other.ordering if isinstance( other, type(self)) else False ) @classmethod def check(cls, **kwargs): errors = super().check(**kwargs) if not cls._meta.ordering: errors.append( checks.Error( 'The ordering of "%s" is undefined.' % cls._meta.label, obj=cls, id="admin_ordering.E002", hint="Make the inner Meta class inherit OrderableModel.Meta.", ) ) return errors