Author: russellm
Date: 2010-10-28 07:57:04 -0500 (Thu, 28 Oct 2010)
New Revision: 14389
Modified:
django/trunk/django/db/models/fields/related.py
django/trunk/tests/regressiontests/multiple_database/models.py
django/trunk/tests/regressiontests/multiple_database/tests.py
Log:
Fixed #14471 -- Corrected a regression in the use of methods on custom managers
on related querysets. Thanks to Lucky for the report.
Modified: django/trunk/django/db/models/fields/related.py
===================================================================
--- django/trunk/django/db/models/fields/related.py 2010-10-28 12:56:44 UTC
(rev 14388)
+++ django/trunk/django/db/models/fields/related.py 2010-10-28 12:57:04 UTC
(rev 14389)
@@ -420,7 +420,7 @@
def create(self, **kwargs):
kwargs.update({rel_field.name: instance})
db = router.db_for_write(rel_model, instance=instance)
- return super(RelatedManager, self).using(db).create(**kwargs)
+ return super(RelatedManager,
self.db_manager(db)).create(**kwargs)
create.alters_data = True
def get_or_create(self, **kwargs):
@@ -428,7 +428,7 @@
# ForeignRelatedObjectsDescriptor knows about.
kwargs.update({rel_field.name: instance})
db = router.db_for_write(rel_model, instance=instance)
- return super(RelatedManager,
self).using(db).get_or_create(**kwargs)
+ return super(RelatedManager,
self.db_manager(db)).get_or_create(**kwargs)
get_or_create.alters_data = True
# remove() and clear() are only provided if the ForeignKey can
have a value of null.
@@ -517,7 +517,7 @@
opts = through._meta
raise AttributeError("Cannot use create() on a ManyToManyField
which specifies an intermediary model. Use %s.%s's Manager instead." %
(opts.app_label, opts.object_name))
db = router.db_for_write(self.instance.__class__,
instance=self.instance)
- new_obj = super(ManyRelatedManager,
self).using(db).create(**kwargs)
+ new_obj = super(ManyRelatedManager,
self.db_manager(db)).create(**kwargs)
self.add(new_obj)
return new_obj
create.alters_data = True
@@ -525,7 +525,7 @@
def get_or_create(self, **kwargs):
db = router.db_for_write(self.instance.__class__,
instance=self.instance)
obj, created = \
- super(ManyRelatedManager,
self).using(db).get_or_create(**kwargs)
+ 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:
Modified: django/trunk/tests/regressiontests/multiple_database/models.py
===================================================================
--- django/trunk/tests/regressiontests/multiple_database/models.py
2010-10-28 12:56:44 UTC (rev 14388)
+++ django/trunk/tests/regressiontests/multiple_database/models.py
2010-10-28 12:57:04 UTC (rev 14389)
@@ -30,7 +30,21 @@
class Meta:
ordering = ('name',)
+# This book manager doesn't do anything interesting; it just
+# exists to strip out the 'extra_arg' argument to certain
+# calls. This argument is used to establish that the BookManager
+# is actually getting used when it should be.
+class BookManager(models.Manager):
+ def create(self, *args, **kwargs):
+ kwargs.pop('extra_arg', None)
+ return super(BookManager, self).create(*args, **kwargs)
+
+ def get_or_create(self, *args, **kwargs):
+ kwargs.pop('extra_arg', None)
+ return super(BookManager, self).get_or_create(*args, **kwargs)
+
class Book(models.Model):
+ objects = BookManager()
title = models.CharField(max_length=100)
published = models.DateField()
authors = models.ManyToManyField(Person)
@@ -60,4 +74,3 @@
class Meta:
ordering = ('flavor',)
-
Modified: django/trunk/tests/regressiontests/multiple_database/tests.py
===================================================================
--- django/trunk/tests/regressiontests/multiple_database/tests.py
2010-10-28 12:56:44 UTC (rev 14388)
+++ django/trunk/tests/regressiontests/multiple_database/tests.py
2010-10-28 12:57:04 UTC (rev 14389)
@@ -891,7 +891,29 @@
except ValueError:
pass
+ def test_related_manager(self):
+ "Related managers return managers, not querysets"
+ mark = Person.objects.using('other').create(name="Mark Pilgrim")
+ # extra_arg is removed by the BookManager's implementation of
+ # create(); but the BookManager's implementation won't get called
+ # unless edited returns a Manager, not a queryset
+ mark.book_set.create(title="Dive into Python",
+ published=datetime.date(2009, 5, 4),
+ extra_arg=True)
+
+ mark.book_set.get_or_create(title="Dive into Python",
+ published=datetime.date(2009, 5, 4),
+ extra_arg=True)
+
+ mark.edited.create(title="Dive into Water",
+ published=datetime.date(2009, 5, 4),
+ extra_arg=True)
+
+ mark.edited.get_or_create(title="Dive into Water",
+ published=datetime.date(2009, 5, 4),
+ extra_arg=True)
+
class TestRouter(object):
# A test router. The behaviour is vaguely master/slave, but the
# databases aren't assumed to propagate changes.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.