aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/changelog.rst1
-rw-r--r--docs/orms.rst9
-rw-r--r--factory/django.py8
-rw-r--r--tests/djapp/settings.py3
-rw-r--r--tests/test_django.py10
-rw-r--r--tests/test_using.py6
6 files changed, 34 insertions, 3 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 0cf8368..c2da698 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -11,6 +11,7 @@ ChangeLog
- Add support for getting/setting :mod:`factory.fuzzy`'s random state (see :issue:`175`, :issue:`185`).
- Support lazy evaluation of iterables in :class:`factory.fuzzy.FuzzyChoice` (see :issue:`184`).
+ - Support non-default databases at the factory level (see :issue:`171`)
*Bugfix:*
diff --git a/docs/orms.rst b/docs/orms.rst
index a0afc40..5105e66 100644
--- a/docs/orms.rst
+++ b/docs/orms.rst
@@ -42,7 +42,14 @@ All factories for a Django :class:`~django.db.models.Model` should use the
.. class:: DjangoOptions(factory.base.FactoryOptions)
- The ``class Meta`` on a :class:`~DjangoModelFactory` supports an extra parameter:
+ The ``class Meta`` on a :class:`~DjangoModelFactory` supports extra parameters:
+
+ .. attribute:: database
+
+ .. versionadded:: 2.5.0
+
+ All queries to the related model will be routed to the given database.
+ It defaults to ``'default'``.
.. attribute:: django_get_or_create
diff --git a/factory/django.py b/factory/django.py
index e823ee9..ee5749a 100644
--- a/factory/django.py
+++ b/factory/django.py
@@ -56,6 +56,7 @@ class DjangoOptions(base.FactoryOptions):
def _build_default_options(self):
return super(DjangoOptions, self)._build_default_options() + [
base.OptionDefault('django_get_or_create', (), inherit=True),
+ base.OptionDefault('database', 'default', inherit=True),
]
def _get_counter_reference(self):
@@ -100,9 +101,12 @@ class DjangoModelFactory(base.Factory):
raise base.AssociatedClassError("No model set on %s.%s.Meta"
% (cls.__module__, cls.__name__))
try:
- return model_class._default_manager # pylint: disable=W0212
+ manager = model_class._default_manager # pylint: disable=W0212
except AttributeError:
- return model_class.objects
+ manager = model_class.objects
+
+ manager = manager.using(cls._meta.database)
+ return manager
@classmethod
def _get_or_create(cls, model_class, *args, **kwargs):
diff --git a/tests/djapp/settings.py b/tests/djapp/settings.py
index c051faf..18e43dd 100644
--- a/tests/djapp/settings.py
+++ b/tests/djapp/settings.py
@@ -34,6 +34,9 @@ DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
},
+ 'replica': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ },
}
diff --git a/tests/test_django.py b/tests/test_django.py
index 4653305..a8f1f77 100644
--- a/tests/test_django.py
+++ b/tests/test_django.py
@@ -165,6 +165,16 @@ class ModelTests(django_test.TestCase):
self.assertRaises(factory.FactoryError, UnsetModelFactory.create)
+ def test_cross_database(self):
+ class OtherDBFactory(factory.django.DjangoModelFactory):
+ class Meta:
+ model = models.StandardModel
+ database = 'replica'
+
+ obj = OtherDBFactory()
+ self.assertFalse(models.StandardModel.objects.exists())
+ self.assertEqual(obj, models.StandardModel.objects.using('replica').get())
+
@unittest.skipIf(django is None, "Django not installed.")
class DjangoPkSequenceTestCase(django_test.TestCase):
diff --git a/tests/test_using.py b/tests/test_using.py
index 7318f2e..1d7977f 100644
--- a/tests/test_using.py
+++ b/tests/test_using.py
@@ -69,6 +69,9 @@ class FakeModel(object):
def order_by(self, *args, **kwargs):
return [1]
+ def using(self, db):
+ return self
+
objects = FakeModelManager()
def __init__(self, **kwargs):
@@ -1490,6 +1493,9 @@ class BetterFakeModelManager(object):
instance.id = 2
return instance, True
+ def using(self, db):
+ return self
+
class BetterFakeModel(object):
@classmethod