[Solved]-Re-ordering entries in a model using drag-and-drop

6👍

For working code to do this, check out snippet 1053 at djangosnippets.org.

4👍

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.

👤S.Lott

3👍

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

2👍

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.

1👍

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’].

0👍

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').

Leave a comment