diff options
author | Alex Gaynor <alex.gaynor@gmail.com> | 2009-12-16 07:01:56 +0000 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2009-12-16 07:01:56 +0000 |
commit | fc36471d1b9d672bb49714c36d016ac4ebb95ea8 (patch) | |
tree | 81764f08c330d7aa0888a2f0d310a0c36e0f74b4 | |
parent | 05b4d2f67bc3e75d2d1aada844d6031cc126e48e (diff) | |
download | django-fc36471d1b9d672bb49714c36d016ac4ebb95ea8.tar.gz |
[soc2009/multidb] Fixed a problem with m2m descriptors not sticking to the right database. Patch from Russell Keith-Magee.
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11873 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | django/db/models/fields/related.py | 13 | ||||
-rw-r--r-- | tests/regressiontests/multiple_database/tests.py | 21 |
3 files changed, 32 insertions, 5 deletions
@@ -5,6 +5,9 @@ Required for v1.2 ~~~~~~~~~~~~~~~~~ * Modify the admin interface to support multiple databases (doh). + - Document how it is done + - Modify m2m widgets to stick to the same database as parent + - Modify inlines to stick to same database as parent Optional for v1.2 ~~~~~~~~~~~~~~~~~ diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 84a0a7a74f..7d5a41389a 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -439,7 +439,7 @@ def create_many_related_manager(superclass, rel=False): raise ValueError("%r instance needs to have a primary key value before a many-to-many relationship can be used." % instance.__class__.__name__) def get_query_set(self): - return superclass.get_query_set(self)._next_is_sticky().filter(**(self.core_filters)) + return superclass.get_query_set(self).using(self.instance._state.db)._next_is_sticky().filter(**(self.core_filters)) # If the ManyToMany relation has an intermediary model, # the add and remove methods do not exist. @@ -709,7 +709,7 @@ class ManyToManyRel(object): class ForeignKey(RelatedField, Field): """Foreign Key (type determined by related field)""" - + empty_strings_allowed = False def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs): try: @@ -809,7 +809,7 @@ class ForeignKey(RelatedField, Field): class OneToOneField(ForeignKey): """One-to-one relationship - + A OneToOneField is essentially the same as a ForeignKey, with the exception that always carries a "unique" constraint with it and the reverse relation always returns the object pointed to (since there will only ever be one), @@ -869,7 +869,7 @@ def create_many_to_many_intermediary_model(field, klass): class ManyToManyField(RelatedField, Field): """Many-to-many relationship""" - + def __init__(self, to, **kwargs): try: assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name) @@ -1032,7 +1032,10 @@ class ManyToManyField(RelatedField, Field): setattr(instance, self.attname, data) def formfield(self, **kwargs): - defaults = {'form_class': forms.ModelMultipleChoiceField, 'queryset': self.rel.to._default_manager.complex_filter(self.rel.limit_choices_to)} + defaults = { + 'form_class': forms.ModelMultipleChoiceField, + 'queryset': self.rel.to._default_manager.complex_filter(self.rel.limit_choices_to) + } defaults.update(kwargs) # If initial is passed in, it's a list of related objects, but the # MultipleChoiceField takes a list of IDs. diff --git a/tests/regressiontests/multiple_database/tests.py b/tests/regressiontests/multiple_database/tests.py index 2c0e4b6a53..cce669ec4c 100644 --- a/tests/regressiontests/multiple_database/tests.py +++ b/tests/regressiontests/multiple_database/tests.py @@ -160,6 +160,17 @@ class QueryTestCase(TestCase): self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)), [u'Dive into Python']) + # Reget the objects to clear caches + dive = Book.objects.using('other').get(title="Dive into Python") + mark = Author.objects.using('other').get(name="Mark Pilgrim") + + # Retrive related object by descriptor. Related objects should be database-baound + self.assertEquals(list(dive.authors.all().values_list('name', flat=True)), + [u'Mark Pilgrim']) + + self.assertEquals(list(mark.book_set.all().values_list('title', flat=True)), + [u'Dive into Python']) + def test_m2m_forward_operations(self): "M2M forward manipulations are all constrained to a single DB" # Create a book and author on the other database @@ -286,6 +297,16 @@ class QueryTestCase(TestCase): self.assertEquals(list(Book.objects.using('other').filter(favourite_of__name='Mark Pilgrim').values_list('title', flat=True)), [u'Dive into Python']) + # Reget the objects to clear caches + dive = Book.objects.using('other').get(title="Dive into Python") + mark = Author.objects.using('other').get(name="Mark Pilgrim") + + # Retrive related object by descriptor. Related objects should be database-baound + self.assertEquals(list(dive.favourite_of.all().values_list('name', flat=True)), + [u'Mark Pilgrim']) + + self.assertEquals(mark.favourite_book.title, u'Dive into Python') + def test_foreign_key_reverse_operations(self): "FK reverse manipulations are all constrained to a single DB" dive = Book.objects.using('other').create(title="Dive into Python", |