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)
Change History (12)
by , 15 years ago
Attachment: | object_list_404.diff added |
---|
comment:1 by , 15 years ago
Needs tests: | set |
---|
comment:2 by , 15 years ago
Patch needs improvement: | set |
---|
comment:3 by , 15 years ago
Summary: | get_object/list_or_404 methods → get_object/list_or_none methods |
---|
Whoops, obvious oversight! I forgot to wrap list() around the return value for get_list_or_none().
by , 15 years ago
Attachment: | object_list_404-2.diff added |
---|
Modification: wraps get_list_or_none() return value in list()
comment:4 by , 15 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
comment:5 by , 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 , 15 years ago
Returning a list from get_object_or_none makes no sense to me, it should return None
.
comment:7 by , 14 years ago
Severity: | → Normal |
---|---|
Type: | → New feature |
comment:8 by , 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 , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
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.
Adds get_list_or_none and get_object_or_none methods to django.shortcuts