Opened 15 years ago

Closed 13 years ago

#11352 closed New feature (wontfix)

get_object/list_or_none methods

Reported by: Chuck Harmston Owned by: nobody
Component: Core (Other) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hey all,

First time contributor (not just to Django, but to any open source project), so go easy on me.

Several times I've found myself wanting for a get_list_or_none() shortcut method. get_list_or_404 is nice, but there are some instances (search results, for example) where returning an empty QuerySet makes much more sense. Attached is a patch adding functional get_list_or_404 and get_object_or_404 methods to django.shortcuts. I am aware that in #2659 Adrian rejected get_object_or_404 as scope creep, but since that time objects.none() has been introduced, which would render these methods much more useful. Feel free to set it as wontfix if you still think it's scope creep, but these are certainly useful methods for me, and I'm sure they would be for others as well.

I have not run unit tests on this; it seems to me that it would make more sense to get community buy-in on the necessity for these methods first.

Feedback welcome. Thanks all!

Attachments (3)

object_list_404.diff (1.7 KB ) - added by Chuck Harmston 15 years ago.
Adds get_list_or_none and get_object_or_none methods to django.shortcuts
object_list_404-2.diff (1.7 KB ) - added by Chuck Harmston 15 years ago.
Modification: wraps get_list_or_none() return value in list()
object_list_404-3.diff (9.1 KB ) - added by Chuck Harmston 15 years ago.
Adds tests and documentation

Download all attachments as: .zip

Change History (12)

by Chuck Harmston, 15 years ago

Attachment: object_list_404.diff added

Adds get_list_or_none and get_object_or_none methods to django.shortcuts

comment:1 by Chuck Harmston, 15 years ago

Needs tests: set

comment:2 by Alex Gaynor, 15 years ago

Patch needs improvement: set

comment:3 by Chuck Harmston, 15 years ago

Summary: get_object/list_or_404 methodsget_object/list_or_none methods

Whoops, obvious oversight! I forgot to wrap list() around the return value for get_list_or_none().

by Chuck Harmston, 15 years ago

Attachment: object_list_404-2.diff added

Modification: wraps get_list_or_none() return value in list()

comment:4 by Alex Gaynor, 15 years ago

Triage Stage: UnreviewedDesign decision needed

by Chuck Harmston, 15 years ago

Attachment: object_list_404-3.diff added

Adds tests and documentation

comment:5 by Chuck Harmston, 15 years ago

Needs tests: unset
Patch needs improvement: unset

Added a new patch with proper documentation and unit tests.

Sidebar: it may be worth considering renaming tests/get_object_or_404 to something like tests/dbapi_shortcuts.

comment:6 by Alex Gaynor, 15 years ago

Returning a list from get_object_or_none makes no sense to me, it should return None .

comment:7 by Julien Phalip, 14 years ago

Severity: Normal
Type: New feature

comment:8 by Ori Livneh, 13 years ago

Easy pickings: unset
UI/UX: unset

I'm having a hard time understanding the rationale behind this feature. This pattern seems rather obscure, rather than so commonplace so as to warrant a shortcut method.

You can already do this quite succinctly:

query_set = Book.objects.filter(pk=999)
val = query_set.get() if query_set else Book.objects.none()

(This assumes that your query set may return one or no results. A larger result set will cause a MultipleObjectsReturned exception to be raised.)

It's possible I'm missing something obvious, but I can't help the feeling that having functions that expect a model instance or an empty QuerySet is an anti-pattern. A QuerySet is a collection; an empty QuerySet is still just an empty collection. Alex's proposal (that get_object_or_none return None instead) is more palatable, but I think that in order for this to be compelling a realistic use-case ought to be presented.

comment:9 by Luke Plant, 13 years ago

Resolution: wontfix
Status: newclosed

I agree with Ori that I can't see the rationale for these:

1) get_object_or_none is unhelpful - it returns either a single object or an empty QuerySet, which means you then still need to test what type of thing you've got i.e. a list of things or a single thing, which I agree seems to promote an anti-pattern. If you just want to silence the DoesNotExist you get from the get() call if there are no matching items - don't use get(), just use list() on the QuerySet. The only other case this function would be useful is if you want an empty list for the case where get() returns zero items or it returns more than 1 item, but you want a single object if it returns exactly 1 item. This is certainly not a common case in my experience.

2) get_list_or_none seems even more bizarre. This method just seems to be a rather inefficient way of doing list(queryset.filter(**kwargs)) - list(queryset.none()) is always exactly equal to an empty list, and empty lists are empty lists. (It's also incorrectly documented as having something to do with DoesNotExist exceptions).

I think these things must be based on some misconception about how lists in Python work, or something, I'm afraid I can't work out the intention here.

Note: See TracTickets for help on using tickets.
Back to Top