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

Comments

erikcw (on April 16, 2009):
<p>Here is the full "move()" model method. I added some smarts to the algorithm to prevent "skipping".</p> <p></p> <pre>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() </pre> <p></p>

#

Please login first before commenting.