tickets: 8318
This data as json
id | created | changetime | last_pulled_from_trac | stage | status | component | type | severity | version | resolution | summary | description | owner | reporter | keywords | easy | has_patch | needs_better_patch | needs_tests | needs_docs | ui_ux |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
8318 | 2008-08-14 17:39:57 | 2011-09-28 16:12:17 | 2022-03-06 03:41:56.194187 | Unreviewed | closed | Database layer (models, ORM) | dev | duplicate | Unexpected behavior with ManyRelatedManager get_or_create() | I've noticed 2 things happening when using a ManyRelatedManager get_or_create method: 1. The new related object is created but not added to the current object. Looking at django/db/models/fields/related.py, get_or_create is not overridden() in the ManyRelatedManager definition, but create() is to add the new object. 2. Using get_or_create() to add a new object that already exists regardless of whether or not it's linked to the current object results in a related object DoesNotExist exception. {{{ from django.db import models class Controller(models.Model): name = models.CharField(max_length=30, unique=True) def __unicode__(self): return self.name class ControllerGroup(models.Model): name = models.CharField(max_length=30, unique=True) controllers = models.ManyToManyField(Controller) def __unicode__(self): return self.name # create a controller >>> c1 = Controller(name='controller1').save() # create a controller group >>> cg = ControllerGroup(name='my group').save() # 'add' using get_or_create() >>> cg.controllers.get_or_create(name='controller1') Traceback (most recent call last): File "<console>", line 1, in <module> File "/usr/local/django/src/trunk/django/db/models/manager.py", line 84, in get_or_create return self.get_query_set().get_or_create(**kwargs) File "/usr/local/django/src/trunk/django/db/models/query.py", line 335, in get_or_create return self.get(**kwargs), False File "/usr/local/django/src/trunk/django/db/models/query.py", line 300, in get % self.model._meta.object_name) DoesNotExist: Controller matching query does not exist. # trying 'adding' a controller that doesn't exist >>> cg.controllers.get_or_create(name='controller2') (<Controller: controller2>, True) # looks like it's been added, let's check >>> cg.controllers.all() [] }}} | nobody | fredbartle | many related manager get_or_create | 0 | 1 | 1 | 0 | 0 | 0 |