#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.

Reply via email to