Opened 8 years ago
Closed 8 years ago
#26638 closed New feature (fixed)
Allow callable in defaults argument for QuerySet.get_or_create
Reported by: | Maxime Lorant | Owned by: | Will Koster |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Will Koster | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | yes | UI/UX: | no |
Description (last modified by )
It would be nice if get_or_create
handles callable in the defaults
parameter so the defaults value are not computed at each selection. Indeed, if your default values for insertion contains selection of related object or any long computation, it is done at each call, even if the object can be retrieved without insertion (and so the defaults parameter is not used).
In term of code, I would like to do something like this:
SomeObject.objects.get_or_create( key1=value1, key2=value2, defaults={ 'key3': lambda: long_processing_to_get_default(), # or even 'key3': lambda: OtherModel.objects.get(pk=request.some_value) } )
For backward-compatibility and ease of writing, it should still accept values that are not callables. See the patch attached (unit tests are missing so it is not complete!) My patch is wrong in fact: it computes the value before the selection and it consider the dict as a whole callable instead of a single key of the dict... Anyway the implementation inside the except DoesNotExist
should be easy :)
Attachments (1)
Change History (10)
by , 8 years ago
Attachment: | patch26638.txt added |
---|
comment:1 by , 8 years ago
Description: | modified (diff) |
---|
comment:2 by , 8 years ago
Description: | modified (diff) |
---|
comment:3 by , 8 years ago
comment:4 by , 8 years ago
Has patch: | set |
---|---|
Needs tests: | set |
Owner: | changed from | to
Status: | new → assigned |
comment:5 by , 8 years ago
Needs tests: | unset |
---|
comment:6 by , 8 years ago
Needs documentation: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:7 by , 8 years ago
Cc: | added |
---|
comment:8 by , 8 years ago
Needs documentation: | unset |
---|---|
Patch needs improvement: | set |
Left comments for improvement on the PR. Please uncheck "Patch needs improvement" after updating.
I sent a pull request that solves this (https://github.com/django/django/pull/6650). My understanding of the ticket is that it should evaluate the callable if and only if the object needs to be created, and that's what the code does. Is that right?
Also, it passes all the tests under SQLite.