Author: Alex
Date: 2009-11-23 10:44:47 -0600 (Mon, 23 Nov 2009)
New Revision: 11774
Modified:
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/models.py
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/tests.py
Log:
[soc2009/multidb] Added test cases for cross-database assignment. Patch from
Russell Keith-Magee.
Modified:
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/models.py
===================================================================
---
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/models.py
2009-11-23 16:44:38 UTC (rev 11773)
+++
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/models.py
2009-11-23 16:44:47 UTC (rev 11774)
@@ -18,3 +18,6 @@
def __unicode__(self):
return self.name
+
+ class Meta:
+ ordering = ('name',)
Modified:
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/tests.py
===================================================================
---
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/tests.py
2009-11-23 16:44:38 UTC (rev 11773)
+++
django/branches/soc2009/multidb/tests/regressiontests/multiple_database/tests.py
2009-11-23 16:44:47 UTC (rev 11774)
@@ -21,7 +21,7 @@
"Objects created on the default database don't leak onto other
databases"
# Create a book on the default database using create()
Book.objects.create(title="Pro Django",
- published=datetime.date(2008, 12, 16))
+ published=datetime.date(2008, 12, 16))
# Create a book on the default database using a save
dive = Book()
@@ -57,7 +57,7 @@
"Objects created on another database don't leak onto the default
database"
# Create a book on the second database
Book.objects.using('other').create(title="Pro Django",
- published=datetime.date(2008, 12, 16))
+ published=datetime.date(2008, 12,
16))
# Create a book on the default database using a save
dive = Book()
@@ -130,13 +130,13 @@
"M2M fields are constrained to a single database"
# Create a book and author on the default database
pro = Book.objects.create(title="Pro Django",
- published=datetime.date(2008, 12, 16))
+ published=datetime.date(2008, 12, 16))
marty = Author.objects.create(name="Marty Alchin")
# Create a book and author on the other database
dive = Book.objects.using('other').create(title="Dive into Python",
-
published=datetime.date(2009, 5, 4))
+
published=datetime.date(2009, 5, 4))
mark = Author.objects.using('other').create(name="Mark Pilgrim")
@@ -164,7 +164,7 @@
"M2M forward manipulations are all constrained to a single DB"
# Create a book and author on the other database
dive = Book.objects.using('other').create(title="Dive into Python",
-
published=datetime.date(2009, 5, 4))
+
published=datetime.date(2009, 5, 4))
mark = Author.objects.using('other').create(name="Mark Pilgrim")
@@ -208,7 +208,7 @@
"M2M reverse manipulations are all constrained to a single DB"
# Create a book and author on the other database
dive = Book.objects.using('other').create(title="Dive into Python",
-
published=datetime.date(2009, 5, 4))
+
published=datetime.date(2009, 5, 4))
mark = Author.objects.using('other').create(name="Mark Pilgrim")
@@ -252,13 +252,13 @@
"FK fields are constrained to a single database"
# Create a book and author on the default database
pro = Book.objects.create(title="Pro Django",
- published=datetime.date(2008, 12, 16))
+ published=datetime.date(2008, 12, 16))
marty = Author.objects.create(name="Marty Alchin")
# Create a book and author on the other database
dive = Book.objects.using('other').create(title="Dive into Python",
-
published=datetime.date(2009, 5, 4))
+
published=datetime.date(2009, 5, 4))
mark = Author.objects.using('other').create(name="Mark Pilgrim")
@@ -275,12 +275,6 @@
mark = Author.objects.using('other').get(name='Mark Pilgrim')
self.assertEquals(mark.favourite_book.title, "Dive into Python")
- try:
- marty.favourite_book = mark
- self.fail("Shouldn't be able to assign across databases")
- except Exception: # FIXME - this should be more explicit
- pass
-
# Check that queries work across foreign key joins
self.assertEquals(list(Book.objects.using('default').filter(favourite_of__name='Marty
Alchin').values_list('title', flat=True)),
[u'Pro Django'])
@@ -336,6 +330,125 @@
self.assertEquals(list(Book.objects.using('other').filter(favourite_of__name='Jane
Brown').values_list('title', flat=True)),
[u'Dive into Python'])
+ def test_m2m_cross_database_protection(self):
+ "Operations that involve sharing M2M objects across databases raise an
error"
+ # Create a book and author on the default database
+ pro = Book.objects.create(title="Pro Django",
+ published=datetime.date(2008, 12, 16))
+
+ marty = Author.objects.create(name="Marty Alchin")
+
+ # Create a book and author on the other database
+ dive = Book.objects.using('other').create(title="Dive into Python",
+
published=datetime.date(2009, 5, 4))
+
+ mark = Author.objects.using('other').create(name="Mark Pilgrim")
+ # Set a foreign key set with an object from a different database
+ try:
+ marty.book_set = [pro, dive]
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # Add to an m2m with an object from a different database
+ try:
+ marty.book_set.add(dive)
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # Set a m2m with an object from a different database
+ try:
+ marty.book_set = [pro, dive]
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # Add to a reverse m2m with an object from a different database
+ try:
+ dive.authors.add(marty)
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # Set a reverse m2m with an object from a different database
+ try:
+ dive.authors = [mark, marty]
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ def test_foreign_key_cross_database_protection(self):
+ "Operations that involve sharing FK objects across databases raise an
error"
+ # Create a book and author on the default database
+ pro = Book.objects.create(title="Pro Django",
+ published=datetime.date(2008, 12, 16))
+
+ marty = Author.objects.create(name="Marty Alchin")
+
+ # Create a book and author on the other database
+ dive = Book.objects.using('other').create(title="Dive into Python",
+
published=datetime.date(2009, 5, 4))
+
+ mark = Author.objects.using('other').create(name="Mark Pilgrim")
+
+ # Set a foreign key with an object from a different database
+ try:
+ marty.favourite_book = dive
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # Set a foreign key set with an object from a different database
+ try:
+ dive.favourite_of = [mark, marty]
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # Add to a foreign key set with an object from a different database
+ try:
+ dive.favourite_of.add(marty)
+ self.fail("Shouldn't be able to assign across databases")
+ except ValueError:
+ pass
+
+ # BUT! if you assign a FK object when the base object hasn't
+ # been saved yet, you implicitly assign the database for the
+ # base object.
+ john = Author(name="John Smith")
+ # initially, no db assigned
+ self.assertEquals(john._state.db, None)
+
+ # Dive comes from 'other', so john is set to use 'other'...
+ john.favourite_book = dive
+ self.assertEquals(john._state.db, 'other')
+ # ... but it isn't saved yet
+
self.assertEquals(list(Author.objects.using('other').values_list('name',flat=True)),
+ [u'Mark Pilgrim'])
+
+ # When saved, John goes to 'other'
+ john.save()
+
self.assertEquals(list(Author.objects.using('default').values_list('name',flat=True)),
+ [u'Marty Alchin'])
+
self.assertEquals(list(Author.objects.using('other').values_list('name',flat=True)),
+ [u'John Smith', u'Mark Pilgrim'])
+
+ # This also works if you assign the FK in the constructor
+ jane = Author(name='Jane Brown', favourite_book=dive)
+ self.assertEquals(jane._state.db, 'other')
+ # ... but it isn't saved yet
+
self.assertEquals(list(Author.objects.using('other').values_list('name',flat=True)),
+ [u'John Smith', u'Mark Pilgrim'])
+
+ # When saved, Jane goes to 'other'
+ jane.save()
+
self.assertEquals(list(Author.objects.using('default').values_list('name',flat=True)),
+ [u'Marty Alchin'])
+
self.assertEquals(list(Author.objects.using('other').values_list('name',flat=True)),
+ [u'Jane Brown', u'John Smith', u'Mark Pilgrim'])
+
+
class FixtureTestCase(TestCase):
multi_db = True
fixtures = ['multidb-common', 'multidb']
--
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=.