SortableModel - abstract model class for sortable records

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class SortableModel(models.Model):
    """ 
    Abstract model which makes an inherited model's records sortable
    by calling instance.move(position)
    """
    order = models.IntegerField(default=0)

    class Meta:
        abstract = True
        ordering = ['order']

    @staticmethod
    def pre_save(sender, instance, **kwargs):
        """ 
        makes sure we have a value for order. This must be connected to the
        pre_save event for the inheriting model.
        """
        if not instance.order or instance.order == 0:
            #get last order
            try:
                last = sender.objects.values('order').order_by('-order')[0]
                instance.order = last['order'] + 1 
            except IndexError:
                instance.order = 1 
     

    def move(self, to):
        to = int(to)
        orig = self.order
        if to == orig:
            return
     
        # make sure initial ordering is "clean". Not ideal, but sometimes needed
        for i, f in enumerate(ReportField.objects.all()):
            f.order = i+1 
            f.save()

        # make some room
        shift, range = to < orig and (1, (to, orig-1)) or (-1, (orig+1, to))
        ReportField.objects.filter(order__range=range).update(order=F('order')+shift)
     
        # move it
        self.order = to
        self.save()

More like this

  1. "Autoconnect" model decorator, easy pre_save and post_save signal connection by bendavis78 2 years, 10 months ago
  2. Dynamic tabular inlines with optional drag-n-drop sorting by Aneon 4 years ago
  3. Ordered items in the database - alternative by Leonidas 5 years, 11 months ago
  4. PositionField by jpwatts 4 years, 10 months ago
  5. Drag and drop ordering of admin list elements using jQuery UI by johj 2 years, 11 months ago

Comments

(Forgotten your password?)