Code

Opened 4 years ago

Closed 4 years ago

Last modified 3 weeks ago

#13089 closed Uncategorized (wontfix)

Support Negative Indexing on QuerySets

Reported by: adamnelson Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords: feature
Cc: loic@… Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Add support for negative indexing of QuerySets:

Model.objects.all()[:-1]

The result is:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/var/www/pinax-env/lib/python2.6/site-packages/django/db/models/query.py", line 126, in __getitem__
    "Negative indexing is not supported."
AssertionError: Negative indexing is not supported.

Attachments (0)

Change History (12)

comment:1 Changed 4 years ago by dcramer

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

I'm not sure I entirely agree with support, and I think I understand why it's not available: it makes assumptions.

It can also easily be done by doing Model.objects.all().order_by('-id')[0:1]

comment:2 Changed 4 years ago by adamnelson

I don't see what assumption a negative index makes that a positive index would not. Feel free to kill if there is an assumption I'm unaware of.

comment:3 Changed 4 years ago by ubernostrum

  • Resolution set to wontfix
  • Status changed from new to closed

This is a long-standing explicit design decision in the ORM, and so gets a wontfix; if you disagree, feel free to bring it up on the django-developers mailing list and try to build consensus for changing it.

comment:4 Changed 4 years ago by adamnelson

It's not worth the time to rally support with so many more important issues out there. I just figured it was good to get a permanent yes/no in Trac since there's nothing regarding this design decision documented elsewhere. I figured it was a feature that is just difficult to do and would be worth doing at some point.

comment:5 Changed 17 months ago by a.mamish@…

  • Easy pickings unset
  • Severity set to Normal
  • Type set to Uncategorized
  • UI/UX unset

I think this is more important than many think. It's a Python idiom that gets lost in translation. You are emulating lists with the sets and their indexing, it's only natural to support negative indexing as the language does. It surprised me when I started using Django that this didn't work, and I was so happy to be able to do that with Python while typing it too!

comment:6 Changed 13 months ago by anonymous

bump

comment:7 Changed 9 months ago by anonymous

Is there any justification for the design decision? I don't really see how halfway supporting indexing (unless there's some good DB-related reason for it) is good design.

comment:8 follow-up: Changed 9 months ago by loic84

FWIW I'm +1 on this.

I don't like when we stop halfway when emulating a python idiom; either we use our own unrelated API or we comply with the basic expectations that come with the idiom.

In any case, if you care about this, you need to post to the ML; closed tickets receive very little attention so they aren't a good place to debate this kind of decisions.

comment:9 in reply to: ↑ 8 ; follow-up: Changed 9 months ago by django@…

Replying to loic84:

FWIW I'm +1 on this.

I don't like when we stop halfway when emulating a python idiom; either we use our own unrelated API or we comply with the basic expectations that come with the idiom.

In short: querysets are not == lists.

The problem with saying the python negative indexing idiom should be supported is that negative indexing applies nicely to sets, lists, dicts etc where you know the length of the set, list, dict etc.

AFAIK, you can't negative index a generator without first exhausting the generator ... that would be a similar (but not identical) analogy to negative indexing a queryset (ie you have to retrieve the whole queryset before you can know the size).
I realise that the ORM could invert the sort and then re-write the slice for you.

comment:10 in reply to: ↑ 9 Changed 9 months ago by loic84

Replying to django@…:

AFAIK, you can't negative index a generator without first exhausting the generator ... that would be a similar (but not identical) analogy to negative indexing a queryset (ie you have to retrieve the whole queryset before you can know the size).


Negative indexing could be implemented without performance issues, just look at the implementation of QuerySet.__getitem__().

The fancy slicing operations like [::2] which don't translate well to SQL are the real problem, I don't think we need to support those.

comment:11 Changed 9 months ago by loic84

  • Cc loic@… added
  • Has patch set

comment:12 Changed 3 weeks ago by anonymous

+1
violates principle of least surprise

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.