#17198: In admin results can be omitted due to pagination and inadequate
ordering
clauses
-----------------------------------------+------------------------
Reporter: lukeplant | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version:
Severity: Normal | Keywords:
Triage Stage: Accepted | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
In the admin, pagination is achieved using LIMIT/OFFSET. However, if the
ordering specified in the SQL does not totally define an order of rows,
LIMIT/OFFSET is not deterministic with respect to exactly which rows are
returned.
For example, using django.contrib.auth, and suppose you have hundreds of
users with `is_staff == False`. Then,
`User.objects.order_by('is_staff')[0:20]` must return those with `is_staff
== False`, (since these sort first), but it can return any of them. If you
then ask it for `User.objects.order_by('is_staff')[20:40]`, it is
perfectly free to give you same 20 as the first time - since by the same
token it can return any of them.
This means that if you are in the admin, looking at the `User` list and
you have ordered by `is_staff`, paging through the results is not
guaranteed to show you all rows - it could duplicate some and omit others.
I have observed this behaviour in the wild with Postgres. The client in
question was extremely confused as to why, when sorting by a certain
boolean field, some results disappeared, and I was stumped for a while. I
also confirmed from a Django shell that a series of consecutive 'slices'
of a `QuerySet` can return some rows twice and some not at all.
We can argue that the database is being completely correct in what it is
returning, because the question asked is a silly question - you can't
deterministically take items X to Y of a set that doesn't have a strict
total order. But I don't think we can argue that this is not a bug in the
admin - the admin should not be asking the database silly questions.
It applies to any situation where the ordering does not totally define the
order of results returned. It's especially serious for booleans, because
at least half your dataset will share a value.
One possible solution would be to add an ordering by 'pk' to whatever is
explicitly chosen - so you would have `User.objects.order_by('is_staff',
'pk')`. I don't know what performance impact this would have, however.
--
Ticket URL: <https://code.djangoproject.com/ticket/17198>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.