Fixed #13250 -- Corrected a problem with the use of routing rules on the create() call on a Foreign Key. Thanks to chris@xlevus.net for the report.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12895 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
9a8a15ecbb
commit
a75dc3406f
@ -5,7 +5,7 @@ Classes allowing "generic" relations through ContentType and object-id fields.
|
|||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.db.models import signals
|
from django.db.models import signals
|
||||||
from django.db import models
|
from django.db import models, router
|
||||||
from django.db.models.fields.related import RelatedField, Field, ManyToManyRel
|
from django.db.models.fields.related import RelatedField, Field, ManyToManyRel
|
||||||
from django.db.models.loading import get_model
|
from django.db.models.loading import get_model
|
||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
@ -271,7 +271,8 @@ def create_generic_related_manager(superclass):
|
|||||||
def create(self, **kwargs):
|
def create(self, **kwargs):
|
||||||
kwargs[self.content_type_field_name] = self.content_type
|
kwargs[self.content_type_field_name] = self.content_type
|
||||||
kwargs[self.object_id_field_name] = self.pk_val
|
kwargs[self.object_id_field_name] = self.pk_val
|
||||||
return super(GenericRelatedObjectManager, self).create(**kwargs)
|
db = router.db_for_write(self.model, instance=self.instance)
|
||||||
|
return super(GenericRelatedObjectManager, self).using(db).create(**kwargs)
|
||||||
create.alters_data = True
|
create.alters_data = True
|
||||||
|
|
||||||
return GenericRelatedObjectManager
|
return GenericRelatedObjectManager
|
||||||
|
@ -419,7 +419,8 @@ class ForeignRelatedObjectsDescriptor(object):
|
|||||||
|
|
||||||
def create(self, **kwargs):
|
def create(self, **kwargs):
|
||||||
kwargs.update({rel_field.name: instance})
|
kwargs.update({rel_field.name: instance})
|
||||||
return super(RelatedManager, self).create(**kwargs)
|
db = router.db_for_write(rel_model, instance=instance)
|
||||||
|
return super(RelatedManager, self).using(db).create(**kwargs)
|
||||||
create.alters_data = True
|
create.alters_data = True
|
||||||
|
|
||||||
def get_or_create(self, **kwargs):
|
def get_or_create(self, **kwargs):
|
||||||
|
@ -971,6 +971,19 @@ class RouterTestCase(TestCase):
|
|||||||
water = Book(title="Dive into Water", published=datetime.date(2001, 1, 1), editor=mark)
|
water = Book(title="Dive into Water", published=datetime.date(2001, 1, 1), editor=mark)
|
||||||
self.assertEquals(water._state.db, 'default')
|
self.assertEquals(water._state.db, 'default')
|
||||||
|
|
||||||
|
# If you create an object through a FK relation, it will be
|
||||||
|
# written to the write database, even if the original object
|
||||||
|
# was on the read database
|
||||||
|
cheesecake = mark.edited.create(title='Dive into Cheesecake', published=datetime.date(2010, 3, 15))
|
||||||
|
self.assertEquals(cheesecake._state.db, 'default')
|
||||||
|
|
||||||
|
# Same goes for get_or_create, regardless of whether getting or creating
|
||||||
|
cheesecake, created = mark.edited.get_or_create(title='Dive into Cheesecake', published=datetime.date(2010, 3, 15))
|
||||||
|
self.assertEquals(cheesecake._state.db, 'default')
|
||||||
|
|
||||||
|
puddles, created = mark.edited.get_or_create(title='Dive into Puddles', published=datetime.date(2010, 3, 15))
|
||||||
|
self.assertEquals(puddles._state.db, 'default')
|
||||||
|
|
||||||
def test_m2m_cross_database_protection(self):
|
def test_m2m_cross_database_protection(self):
|
||||||
"M2M relations can cross databases if the database share a source"
|
"M2M relations can cross databases if the database share a source"
|
||||||
# Create books and authors on the inverse to the usual database
|
# Create books and authors on the inverse to the usual database
|
||||||
@ -1074,6 +1087,19 @@ class RouterTestCase(TestCase):
|
|||||||
self.assertEquals(Book.authors.through.objects.using('default').count(), 1)
|
self.assertEquals(Book.authors.through.objects.using('default').count(), 1)
|
||||||
self.assertEquals(Book.authors.through.objects.using('other').count(), 0)
|
self.assertEquals(Book.authors.through.objects.using('other').count(), 0)
|
||||||
|
|
||||||
|
# If you create an object through a M2M relation, it will be
|
||||||
|
# written to the write database, even if the original object
|
||||||
|
# was on the read database
|
||||||
|
alice = dive.authors.create(name='Alice')
|
||||||
|
self.assertEquals(alice._state.db, 'default')
|
||||||
|
|
||||||
|
# Same goes for get_or_create, regardless of whether getting or creating
|
||||||
|
alice, created = dive.authors.get_or_create(name='Alice')
|
||||||
|
self.assertEquals(alice._state.db, 'default')
|
||||||
|
|
||||||
|
bob, created = dive.authors.get_or_create(name='Bob')
|
||||||
|
self.assertEquals(bob._state.db, 'default')
|
||||||
|
|
||||||
def test_generic_key_cross_database_protection(self):
|
def test_generic_key_cross_database_protection(self):
|
||||||
"Generic Key operations can span databases if they share a source"
|
"Generic Key operations can span databases if they share a source"
|
||||||
# Create a book and author on the default database
|
# Create a book and author on the default database
|
||||||
@ -1150,6 +1176,13 @@ class RouterTestCase(TestCase):
|
|||||||
review3.content_object = dive
|
review3.content_object = dive
|
||||||
self.assertEquals(review3._state.db, 'default')
|
self.assertEquals(review3._state.db, 'default')
|
||||||
|
|
||||||
|
# If you create an object through a M2M relation, it will be
|
||||||
|
# written to the write database, even if the original object
|
||||||
|
# was on the read database
|
||||||
|
dive = Book.objects.using('other').get(title='Dive into Python')
|
||||||
|
nyt = dive.reviews.create(source="New York Times", content_object=dive)
|
||||||
|
self.assertEquals(nyt._state.db, 'default')
|
||||||
|
|
||||||
def test_subquery(self):
|
def test_subquery(self):
|
||||||
"""Make sure as_sql works with subqueries and master/slave."""
|
"""Make sure as_sql works with subqueries and master/slave."""
|
||||||
# Create a book and author on the other database
|
# Create a book and author on the other database
|
||||||
|
Loading…
x
Reference in New Issue
Block a user