Snippet List
Adds drag-and-drop ordering of rows in the admin list view for Grappelli. This is a updated version of Snippet [#2306](http://djangosnippets.org/snippets/2306/) that works with the current version of Grappelli.
The model needs to have a field holding the position and that field has to be made list_editable in the ModelAdmin. The changes of the ordering are applied after clicking 'Save'.
- django
- sorting
- django-admin
- sortable
- grappelli
I wanted to sort a CharField which consists of digits in a different way. This field is a matricle number field (some kind of registration number for students. They have matricle numbers in the format YYxxxxxx - which means "YY" are the last two digits of the year they started studying.)
So I wanted to sort them in a way that they appear like this:
5000000, 5000001, ... , 9999998, 9999999, 0000000, 0000001, ... , 1200000, ... , 4999999
Took me some time to find out how to do this efficiently in PostgreSQL, and so I thought I'd share it here.
The important stuff is in the model "Candidate" to use a special "objects" object manager which uses a special QuerySet as well. Here lies the "magic": If there is a ordering required that contains "mnr", then a special on-the-fly calculated field will be added to the queryset called "mnr_specialsorted".
Now it is possible to do things like
`Candidate.objects.filter( firstname__contains="Pony" ).exclude( lastname__contains="Java" ).order_by("lastname", "-mnr")`
For other database engines you might want to change the MNR_SORTER variable to fit your needs.
- sort
- orderby
- sorting
- ordering
Having spent ages trying out various admin inline ordering packages and examples I found on here and elsewhere I failed to find a single one that did what I was after in the way I wanted or that worked, so I wrote one!
The general idea for this version was to be done purely in javascript, no additional methods or parameters required on your models, it's designed to be stuck in a js file and included in your admin class Media js parameter:
class Media:
js = ['js/admin/widget_ordering.js', ]
Your model should have an integer column for sorting on, the name of this column should go in the 'sort_column' parameter at line 3 and your model should also obviously specify this in it's Meta 'ordering' class:
class Meta:
ordering = ('rank',)
That's it! This is a pretty basic implementation that adds simple up and down buttons next to the sort order field, if you want to adapt this to use drag and drop or something, please feel free!
- admin
- sorting
- ordering
- inline
- tabular-inlines
This allows you to order the models on the index page of the administration site in a custom way.
This modification goes in the index method of django.contrib.admin.sites.AdminSite. I personally monkey patched it in where my models are loaded and registered with the admin site. Be careful that if you add new models you update the sorting dictionary, else you will get a key error. If no sorting is defined for an app, it will default to alphabetical order.
Note that you'll probably want to also insert this into the app_index function as well.
---
If you like my work, please check out my employer's site at 829llc.com
- Dan
- models
- admin
- sort
- sorting
- app-models
Since r7806, the `User` field is unsorted which makes it harder to find specific users in the list if there is more than a few. This snippet is an `django.contrib.admin.ModelAdmin` subclass which searches through all of the fields on a form and automatically sorts fields which have a relation with `User`. It also filters on having `active=True`.
Just import the `SortedActiveUserModelAdmin` class in your `admin.py` and subclass your `ModelAdmin` classes from it instead of `admin.ModelAdmin`.
- sorting
- modeladmin
- user-foreign-key
**This is a model field for managing user-specified positions.**
Usage
=====
Add a `PositionField` to your model; that's just about it.
If you want to work with all instances of the model as a single collection, there's nothing else required. In order to create collections based on another field in the model (a `ForeignKey`, for example), set `unique_for_field` to the name of the field.
It's probably also a good idea to wrap the `save` method of your model in a transaction since it will trigger another query to reorder the other members of the collection.
Here's a simple example:
from django.db import models, transaction
from positions.fields import PositionField
class List(models.Model):
name = models.CharField(max_length=50)
class Item(models.Model):
list = models.ForeignKey(List, db_index=True)
name = models.CharField(max_length=50)
position = PositionField(unique_for_field='list')
# not required, but probably a good idea
save = transaction.commit_on_success(models.Model.save)
Indices
-------
In general, the value assigned to a `PositionField` will be handled like a list index, to include negative values. Setting the position to `-2` will cause the item to be moved to the second position from the end of the collection -- unless, of course, the collection has fewer than two elements.
Behavior varies from standard list indices when values greater than or less than the maximum or minimum positions are used. In those cases, the value is handled as being the same as the maximum or minimum position, respectively. `None` is also a special case that will cause an item to be moved to the last position in its collection.
Limitations
===========
* Unique constraints can't be applied to `PositionField` because they break the ability to update other items in a collection all at once. This one was a bit painful, because setting the constraint is probably the right thing to do from a database consistency perspective, but the overhead in additional queries was too much to bear.
* After a position has been updated, other members of the collection are updated using a single SQL `UPDATE` statement, this means the `save` method of the other instances won't be called.
More
===
More information, including an example app and tests, is available on [Google Code](http://code.google.com/p/django-positions/).
- lists
- models
- fields
- model
- field
- list
- sorting
- ordering
- collection
- collections
I needed to sort a set of objects (a QuerySet for example) by an externally provided list of IDs - for example:
>>> writers = Writer.objects.all()
>>> sort_by_id_sequence(writers, [3, 1, 2])
[<Writer id: 3>, <Writer id: 1>, <Writer id: 2>]
7 snippets posted so far.