0

The app I am creating shows users a list of items which are all model instances. I want them to be able to sort the items however they would like using JQuery's sortable() method. This is implemented and working properly, but I need a way to save the order in which they are listed. This list is updated somewhat frequently, items being removed and new ones added.

My initial approach was to give the model a "position" column and each time a list item is moved within the list, change the position value of all items in the list. However, this would require me to get all the model objects every time 1 is sorted and apply a change to each one.

The only other way I could come up with was to give each a "weight" value instead of their actual list position. Leave enough space in between each value to fill in gaps. For instance, the weights are 10, 20, 30, & 40. If the user moves the fourth item to the second position, look at the first and second items and pick 15 as its weight. This, of course, will only work so long before all the weights will have to be recalculated in order to place an item.

Am I overthinking this? I don't expect high usage from this app, so the extra model calls using the position column won't really be a problem - but if there is a better, more efficient way to do this I would still prefer to do it that way.

Thanks :-)

Matthias
  • 335
  • 1
  • 3
  • 11

3 Answers3

1

If you must save it for later than you can add a weight or order field to the model and then put logic in to handle the changing weights in an overridden save method. http://docs.djangoproject.com/en/dev/ref/models/instances/#saving-objects http://stackoverflow.com/questions/817284/overriding-the-save-method-in-django-modelform

Then you can use the order by in the query set
http://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

Thomas Schultz
  • 2,446
  • 3
  • 25
  • 36
1

Now you've got me over-thinking this! :)

You could take a linked list style approach. Give your model before and after fields (prev, next, whatever you want to call them). You'll still need your weight field for sorting, but I'd think you could use a character field to sort lexicographically.

So adding a new entry means the standard linked list insert:

  1. set the next field of the new entry
  2. set the prev field to the prev field of the new entry's next field
  3. set the next field of the prev model to the new model.

Additionally you need to choose a weight for your new field. Something like the previous entry's weight with ".1" appended, which will sort fine.

Removal and reordering are similar.

Then you need a cron job to come along and clean up your weights every now and then.

That would reduce you to only hitting a few models when you insert and reorder...

edit: Actually, you probably don't even need the prev and next fields - the lexicographical approach might work just fine - but that's without thinking it through too hard... I think I've thought too much about this already ;)

meshantz
  • 1,566
  • 10
  • 17
0

I would track the sort order in-browser, and make an ajax call to the server each time that the table got sorted, saving the sort order to a session variable. (http://docs.djangoproject.com/en/dev/topics/http/sessions/)

canisrufus
  • 665
  • 2
  • 6
  • 19