Login

Moving items up/down from the admin interface

Author:
vicox
Posted:
September 5, 2008
Language:
Python
Version:
1.0
Tags:
admin ordering moving up/down
Score:
4 (after 4 ratings)

Move Items up and down from the admin interface. Like phpBB does it with its forums.

An additional select field is added to the admin form. After the model has been saved, a model method is called (with the value of the new field), which handles the reordering.

A more detailed description and a screenshot can be found here.

 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
class MyModel(models.Model):
	order = models.IntegerField(editable=False)
	#...

	def move(self, move):
		if move == 'UP':
			mm = MyModel.objects.get(order=self.order-1)
			mm.order += 1
			mm.save()
			self.order -= 1
			self.save()
			#...

class MyModelAdminForm(forms.ModelForm):
	move = forms.CharField(widget=forms.Select)
	move.required = False
	move.widget.choices=(
			(models.BLANK_CHOICE_DASH[0]),
			('FIRST', 'First'),
			('UP', 'Up'),
			('DOWN', 'Down'),
			('LAST', 'Last'),
		)
 
	class Meta:
		model = MyModel

class MyModelAdmin(admin.ModelAdmin):
	form = MyModelAdminForm
 
	def save_model(self, request, obj, form, change):
		obj.save()
		move = form.cleaned_data['move']
		obj.move(move)

admin.site.register(MyModel, MyModelAdmin)

More like this

  1. Ordered items in the database - alternative by Leonidas 8 years, 2 months ago
  2. models with order (+admin editing) by bram 7 years ago
  3. Drag and drop admin list items by chrsgrrtt 5 years ago
  4. SortableModel - abstract model class for sortable records by bendavis78 6 years, 2 months ago
  5. Django admin inline ordering - javascript only implementation by ojhilt 2 years, 8 months ago

Comments

erikcw (on April 16, 2009):

Here is the full "move()" model method. I added some smarts to the algorithm to prevent "skipping".

[HTML_REMOVED]

def save(self, force_insert=False, force_update=False):
    """Custom save to add order property (make last item)."""
    if not self.order: #if this is a new object.
        mm = MyModel.objects.all().latest('order')
        self.order = mm.order + 1
    super(MyModel, self).save(force_insert, force_update)

def move(self, move):
    """Change the ordering of an object."""
    if move == 'UP':
        try:
            mm = MyModel.objects.filter(order__lt=self.order).order_by('-order')[0]
            self.order = mm.order
            mm.order += 1
            mm.save()
            self.save()
        except IndexError:
            pass
    elif move == 'DOWN':
        try:
            mm = MyModel.objects.filter(order__gt=self.order).order_by('order')[0]
            self.order = mm.order
            mm.order -= 1
            mm.save()
            self.save()
        except IndexError:
            pass
    elif move == 'FIRST':
        mm = MyModel.objects.all().order_by('order')[0]
        self.order = mm.order - 1
        self.save()
    elif move == 'LAST':
        mm = MyModel.objects.all().order_by('-order')[0]
        self.order = mm.order + 1
        self.save()

[HTML_REMOVED]

#

Please login first before commenting.