Commit a75dc340 authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

Fixed #13250 -- Corrected a problem with the use of routing rules on the...

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
parent 9a8a15ec
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ Classes allowing "generic" relations through ContentType and object-id fields.
from django.core.exceptions import ObjectDoesNotExist
from django.db import connection
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.loading import get_model
from django.forms import ModelForm
@@ -271,7 +271,8 @@ def create_generic_related_manager(superclass):
        def create(self, **kwargs):
            kwargs[self.content_type_field_name] = self.content_type
            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

    return GenericRelatedObjectManager
+2 −1
Original line number Diff line number Diff line
@@ -419,7 +419,8 @@ class ForeignRelatedObjectsDescriptor(object):

            def create(self, **kwargs):
                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

            def get_or_create(self, **kwargs):
+33 −0
Original line number Diff line number Diff line
@@ -971,6 +971,19 @@ class RouterTestCase(TestCase):
        water = Book(title="Dive into Water", published=datetime.date(2001, 1, 1), editor=mark)
        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):
        "M2M relations can cross databases if the database share a source"
        # 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('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):
        "Generic Key operations can span databases if they share a source"
        # Create a book and author on the default database
@@ -1150,6 +1176,13 @@ class RouterTestCase(TestCase):
        review3.content_object = dive
        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):
        """Make sure as_sql works with subqueries and master/slave."""
        # Create a book and author on the other database