diff options
| author | André Ericson <de.ericson@gmail.com> | 2014-10-08 03:27:31 +0700 |
|---|---|---|
| committer | Loic Bistuer <loic.bistuer@gmail.com> | 2014-10-08 04:55:47 +0700 |
| commit | fa4b6482df08d308fe88044b8c8bf981c6225fb8 (patch) | |
| tree | c988171c48c77266e42a09d483681796ec07c806 /django | |
| parent | dbd52f339cdae7fb57526cb86d45792438799e5b (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.py | 14 | ||||
| -rw-r--r-- | django/db/models/fields/related.py | 21 |
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 |
