summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorAndré Ericson <de.ericson@gmail.com>2014-10-08 03:27:31 +0700
committerLoic Bistuer <loic.bistuer@gmail.com>2014-10-08 04:55:47 +0700
commitfa4b6482df08d308fe88044b8c8bf981c6225fb8 (patch)
treec988171c48c77266e42a09d483681796ec07c806 /django
parentdbd52f339cdae7fb57526cb86d45792438799e5b (diff)
[1.7.x] Fixed #23611 -- update_or_create failing from a related manager
Added update_or_create to RelatedManager, ManyRelatedManager and GenericRelatedObjectManager. Added missing get_or_create to GenericRelatedObjectManager. Conflicts: tests/generic_relations/tests.py tests/get_or_create/tests.py Backport of ed37f7e979 from master
Diffstat (limited to 'django')
-rw-r--r--django/contrib/contenttypes/fields.py14
-rw-r--r--django/db/models/fields/related.py21
2 files changed, 31 insertions, 4 deletions
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index b70a947ddf..a25aa64cb9 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -523,6 +523,20 @@ def create_generic_related_manager(superclass):
return super(GenericRelatedObjectManager, self).using(db).create(**kwargs)
create.alters_data = True
+ def get_or_create(self, **kwargs):
+ kwargs[self.content_type_field_name] = self.content_type
+ kwargs[self.object_id_field_name] = self.pk_val
+ db = router.db_for_write(self.model, instance=self.instance)
+ return super(GenericRelatedObjectManager, self).using(db).get_or_create(**kwargs)
+ get_or_create.alters_data = True
+
+ def update_or_create(self, **kwargs):
+ kwargs[self.content_type_field_name] = self.content_type
+ kwargs[self.object_id_field_name] = self.pk_val
+ db = router.db_for_write(self.model, instance=self.instance)
+ return super(GenericRelatedObjectManager, self).using(db).update_or_create(**kwargs)
+ update_or_create.alters_data = True
+
return GenericRelatedObjectManager
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 868f43090d..d87a9229ef 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -715,13 +715,17 @@ def create_foreign_related_manager(superclass, rel_field, rel_model):
create.alters_data = True
def get_or_create(self, **kwargs):
- # Update kwargs with the related object that this
- # ForeignRelatedObjectsDescriptor knows about.
kwargs[rel_field.name] = self.instance
db = router.db_for_write(self.model, instance=self.instance)
return super(RelatedManager, self.db_manager(db)).get_or_create(**kwargs)
get_or_create.alters_data = True
+ def update_or_create(self, **kwargs):
+ kwargs[rel_field.name] = self.instance
+ db = router.db_for_write(self.model, instance=self.instance)
+ return super(RelatedManager, self.db_manager(db)).update_or_create(**kwargs)
+ update_or_create.alters_data = True
+
# remove() and clear() are only provided if the ForeignKey can have a value of null.
if rel_field.null:
def remove(self, *objs, **kwargs):
@@ -963,8 +967,7 @@ def create_many_related_manager(superclass, rel):
def get_or_create(self, **kwargs):
db = router.db_for_write(self.instance.__class__, instance=self.instance)
- obj, created = \
- super(ManyRelatedManager, self.db_manager(db)).get_or_create(**kwargs)
+ obj, created = super(ManyRelatedManager, self.db_manager(db)).get_or_create(**kwargs)
# We only need to add() if created because if we got an object back
# from get() then the relationship already exists.
if created:
@@ -972,6 +975,16 @@ def create_many_related_manager(superclass, rel):
return obj, created
get_or_create.alters_data = True
+ def update_or_create(self, **kwargs):
+ db = router.db_for_write(self.instance.__class__, instance=self.instance)
+ obj, created = super(ManyRelatedManager, self.db_manager(db)).update_or_create(**kwargs)
+ # We only need to add() if created because if we got an object back
+ # from get() then the relationship already exists.
+ if created:
+ self.add(obj)
+ return obj, created
+ update_or_create.alters_data = True
+
def _add_items(self, source_field_name, target_field_name, *objs):
# source_field_name: the PK fieldname in join table for the source object
# target_field_name: the PK fieldname in join table for the target object