Reputation: 14511
Say I have a blogging app in Django. How can i re-order the posts using a draggable table in the default admin?
It would be best if i didn't have to add any extra fields to the model, but if i really have to i can.
Upvotes: 11
Views: 6676
Reputation: 139
The order can only be determined if you add a field in your model.Let's add a position field in your model.
In your models.py
class MainModel(models.Model):
name = models.CharField(max_length=255)
position = models.PositiveSmallIntegerField(null=True)
class Meta:
ordering = ('position',)
In your apps admin.py
class IdeaCardTagInline(nested_admin.NestedStackedInline):
model = MainModel
extra = 0
min_num = 1
sortable_field_name = "position"
ordering = ('position',)
in Meta will order the MainModel according to the value in the position field.
sortable_field_name = "position"
will help in autofill of the value in position when an user drag and drop the multiple models.
To see the same order in your api, use order_by(x) in views_model.py. Just a model example:
Model.objects.filter().order_by('position').
Upvotes: 0
Reputation: 14162
You may try this snippet https://gist.github.com/barseghyanartur/1ebf927512b18dc2e5be (originally based on this snippet http://djangosnippets.org/snippets/2160/).
Integration is very simple.
Your model (in models.py):
class MyModel(models.Model):
name = models.CharField(max_length=255)
order = models.IntegerField()
# Other fields...
class Meta:
ordering = ('order',)
You admin (admin.py):
class MyModelAdmin(admin.ModelAdmin):
fields = ('name', 'order',) # Add other fields here
list_display = ('name', 'order',)
list_editable = ('order',)
class Media:
js = (
'//code.jquery.com/jquery-1.4.2.js',
'//code.jquery.com/ui/1.8.6/jquery-ui.js',
'path/to/sortable_list.js',
)
Change the JS (of the snippet) accordingly if your attributes responsible for holding the name and ordering are named differently in your model.
Upvotes: 2
Reputation: 22449
There's a nice package for ordering admin objects these days
https://github.com/iambrandontaylor/django-admin-sortable
Also, django-suit has builtin support for this
Upvotes: 3
Reputation: 126541
For working code to do this, check out snippet 1053 at djangosnippets.org.
Upvotes: 6
Reputation: 391818
Note on the "It would be best if i didn't have to add any extra fields to the model, but if i really have to i can."
Sorry, but order of information in a database is determined by the information itself: you always have to add a column for ordering. There's really no choice about that.
Further, to retrieve things in this order, you'll need to specifically add .order_by(x)
to your queries or add ordering
to your model.
class InOrder( models.Model ):
position = models.IntegerField()
data = models.TextField()
class Meta:
ordering = [ 'position' ]
Without the additional field ordering cannot happen. It's one of the rules of relational databases.
Upvotes: 4
Reputation: 32404
In model class you would probably have to add "order" field, to maintain specific order (eg. item with order = 10 is the last one and order = 1 is the first one). Then you can add a JS code in admin change_list template (see this) to maintain drag&drop feature. Finally change ordering in Meta of model to something like ['order'].
Upvotes: 1