#8318 closed (duplicate)
Unexpected behavior with ManyRelatedManager get_or_create()
| Reported by: | Fred Bartle | Owned by: | nobody |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Keywords: | many related manager get_or_create | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | yes |
| Easy pickings: | no | UI/UX: | no |
Description
I've noticed 2 things happening when using a ManyRelatedManager get_or_create method:
- 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.
- 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()
[]
Attachments (2)
Change History (6)
by , 17 years ago
comment:1 by , 17 years ago
| Has patch: | set |
|---|
Code should actually read:
# create a controller >>> c1 = Controller(name='controller1') >>> c1.save() # create a controller group >>> cg = ControllerGroup(name='my group') >>> cg.save()
comment:2 by , 17 years ago
| Patch needs improvement: | set |
|---|
My patch is not correct, I will spend some time reviewing it.
comment:3 by , 17 years ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Note:
See TracTickets
for help on using tickets.
override get_or_create() in ManyRelatedManager