mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
[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
This commit is contained in:
parent
05b4d2f67b
commit
fc36471d1b
3
TODO
3
TODO
@ -5,6 +5,9 @@ Required for v1.2
|
|||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* Modify the admin interface to support multiple databases (doh).
|
* 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
|
Optional for v1.2
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
@ -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__)
|
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):
|
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,
|
# If the ManyToMany relation has an intermediary model,
|
||||||
# the add and remove methods do not exist.
|
# the add and remove methods do not exist.
|
||||||
@ -709,7 +709,7 @@ class ManyToManyRel(object):
|
|||||||
|
|
||||||
class ForeignKey(RelatedField, Field):
|
class ForeignKey(RelatedField, Field):
|
||||||
"""Foreign Key (type determined by related field)"""
|
"""Foreign Key (type determined by related field)"""
|
||||||
|
|
||||||
empty_strings_allowed = False
|
empty_strings_allowed = False
|
||||||
def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
|
def __init__(self, to, to_field=None, rel_class=ManyToOneRel, **kwargs):
|
||||||
try:
|
try:
|
||||||
@ -809,7 +809,7 @@ class ForeignKey(RelatedField, Field):
|
|||||||
|
|
||||||
class OneToOneField(ForeignKey):
|
class OneToOneField(ForeignKey):
|
||||||
"""One-to-one relationship
|
"""One-to-one relationship
|
||||||
|
|
||||||
A OneToOneField is essentially the same as a ForeignKey, with the exception
|
A OneToOneField is essentially the same as a ForeignKey, with the exception
|
||||||
that always carries a "unique" constraint with it and the reverse relation
|
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),
|
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):
|
class ManyToManyField(RelatedField, Field):
|
||||||
"""Many-to-many relationship"""
|
"""Many-to-many relationship"""
|
||||||
|
|
||||||
def __init__(self, to, **kwargs):
|
def __init__(self, to, **kwargs):
|
||||||
try:
|
try:
|
||||||
assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name)
|
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)
|
setattr(instance, self.attname, data)
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
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)
|
defaults.update(kwargs)
|
||||||
# If initial is passed in, it's a list of related objects, but the
|
# If initial is passed in, it's a list of related objects, but the
|
||||||
# MultipleChoiceField takes a list of IDs.
|
# MultipleChoiceField takes a list of IDs.
|
||||||
|
@ -160,6 +160,17 @@ class QueryTestCase(TestCase):
|
|||||||
self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)),
|
self.assertEquals(list(Book.objects.using('other').filter(authors__name='Mark Pilgrim').values_list('title', flat=True)),
|
||||||
[u'Dive into Python'])
|
[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):
|
def test_m2m_forward_operations(self):
|
||||||
"M2M forward manipulations are all constrained to a single DB"
|
"M2M forward manipulations are all constrained to a single DB"
|
||||||
# Create a book and author on the other database
|
# 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)),
|
self.assertEquals(list(Book.objects.using('other').filter(favourite_of__name='Mark Pilgrim').values_list('title', flat=True)),
|
||||||
[u'Dive into Python'])
|
[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):
|
def test_foreign_key_reverse_operations(self):
|
||||||
"FK reverse manipulations are all constrained to a single DB"
|
"FK reverse manipulations are all constrained to a single DB"
|
||||||
dive = Book.objects.using('other').create(title="Dive into Python",
|
dive = Book.objects.using('other').create(title="Dive into Python",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user