Opened 2 years ago
Closed 22 months ago
#34280 closed New feature (fixed)
Support create defaults for update_or_create
Reported by: | Timothy Schilling | Owned by: | Timothy Schilling |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I proposed the idea of extending update_or_create
to support specifying a different set of defaults for the create operation on the [forum](https://forum.djangoproject.com/t/feature-idea-update-or-create-to-allow-different-defaults-for-create-and-update-operations/18300/15). There seems to be consensus it's a positive add to Django.
Adam raised concerns with my proposed approach of adding a create_defaults
parameter to the function since this would conflict with any fields on a model named, create_defaults
. Jeff did a code search on github for that term and didn't find any matches. I suspect if someone where using a field named create_defaults
, it would be a JSON or object type field. Those don't seem like reasonable candidates to be part of a UniqueConstraint
, which should be underlying the look-up arguments to update_or_create
.
I do like the idea of having a separate parameter for create_defaults
, but if we must preserve 100% backwards compatibility, Adam's suggestion of having defaults be set to another object makes the most sense.
My blocking question is, which approach should I take?
From the forum post:
I’ve run into a use-case in which it’d be helpful to have the ability to specify a different set of defaults for the update operation compared to the create operation. While I don’t expect my particular use case to translate, here’s a more generic one.
Given the following Record model:
class Record(models.Model): some_id = models.CharField(unique=True) created_by = models.ForeignKey(User, ...) modified_by = models.ForeignKey(User, null=True, blank=True, ...)When a record is created, we would want to set created_by, but if it’s being updated, we’d want to set modified_by. This use case can’t be solved by using update_or_create, unless it allows for us to specify a different set of default values.
Record.objects.update_or_create( some_id=some_value, defaults={"modified_by": user}, create_defaults={"created_by": user}, )
Change History (7)
comment:1 by , 2 years ago
Owner: | changed from | to
---|
comment:2 by , 2 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 23 months ago
Has patch: | set |
---|
comment:4 by , 23 months ago
Needs documentation: | set |
---|
comment:5 by , 23 months ago
I ended up going with the create_defaults
approach since we have a workaround for the lookup via create_defaults__exact
.
comment:6 by , 22 months ago
Needs documentation: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
Here's a PR with the first version of the changes. https://github.com/django/django/pull/16511