Skip to content

Commit bc0659c

Browse files
committed
Add a database router so dumpdata can ignore embedded models
1 parent 59ace00 commit bc0659c

File tree

7 files changed

+72
-0
lines changed

7 files changed

+72
-0
lines changed

django_mongodb_backend/routers.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from django.apps import apps
2+
3+
from django_mongodb_backend.models import EmbeddedModel
4+
5+
6+
class MongoRouter:
7+
def allow_migrate(self, db, app_label, model_name=None, **hints):
8+
"""
9+
EmbeddedModels don't have their own collection and must be ignored by
10+
dumpdata.
11+
"""
12+
if not model_name:
13+
return None
14+
try:
15+
model = apps.get_model(app_label, model_name)
16+
except LookupError:
17+
return None
18+
return False if issubclass(model, EmbeddedModel) else None

docs/source/faq.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,10 @@ logging::
3232
},
3333
},
3434
}
35+
36+
``dumpdata`` fails with ``CommandError: Unable to serialize database``
37+
----------------------------------------------------------------------
38+
39+
If running ``manage.py dumpdata`` results in ``CommandError: Unable to
40+
serialize database: 'EmbeddedModelManager' object has no attribute using'``,
41+
see :ref:`configuring-database-routers-setting`.

docs/source/intro/configure.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,21 @@ it into the format above, you can use
154154

155155
This constructs a :setting:`DATABASES` setting equivalent to the first example.
156156

157+
.. _configuring-database-routers-setting:
158+
159+
Configuring the ``DATABASE_ROUTERS`` setting
160+
============================================
161+
162+
If you intend to use :doc:`embedded models </topics/embedded-models>`, you must
163+
configure the :setting:`DATABASE_ROUTERS` setting so that a collection for
164+
these models isn't created and so that embedded models won't be treated as
165+
normal models by :djadmin:`dumpdata`::
166+
167+
DATABASE_ROUTERS = ["django_mongodb_backend.routers.MongoRouter"]
168+
169+
(If you've used the :djadmin:`startproject` template, this line is already
170+
present.)
171+
157172
Congratulations, your project is ready to go!
158173

159174
.. seealso::

docs/source/releases/5.0.x.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Django MongoDB Backend 5.0.x
1717
- Added :doc:`async <django:topics/async>` support.
1818
- Added the ``db_name`` parameter to
1919
:func:`~django_mongodb_backend.utils.parse_uri`.
20+
- Added ``django_mongodb_backend.routers.MongoRouter`` to allow
21+
:djadmin:`dumpdata` to ignore embedded models. See
22+
:ref:`configuring-database-routers-setting`.
2023

2124
5.0.0 beta 0
2225
============

docs/source/releases/5.1.x.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ Django MongoDB Backend 5.1.x
1717
- Added :doc:`async <django:topics/async>` support.
1818
- Added the ``db_name`` parameter to
1919
:func:`~django_mongodb_backend.utils.parse_uri`.
20+
- Added ``django_mongodb_backend.routers.MongoRouter`` to allow
21+
:djadmin:`dumpdata` to ignore embedded models. See
22+
:ref:`configuring-database-routers-setting`.
2023

2124
5.1.0 beta 0
2225
============

tests/models_/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
from django.db import models
2+
13
from django_mongodb_backend.models import EmbeddedModel
24

35

46
class Embed(EmbeddedModel):
57
pass
8+
9+
10+
class PlainModel(models.Model):
11+
pass

tests/models_/test_routers.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from django.test import SimpleTestCase
2+
3+
from django_mongodb_backend.routers import MongoRouter
4+
5+
6+
class TestRouter(SimpleTestCase):
7+
def setUp(self):
8+
self.router = MongoRouter()
9+
10+
def test_no_model(self):
11+
self.assertIsNone(self.router.allow_migrate("db", "models_"))
12+
13+
def test_regular_model(self):
14+
self.assertIsNone(self.router.allow_migrate("db", "models_", "plainmodel"))
15+
16+
def test_nonexistent_model(self):
17+
self.assertIsNone(self.router.allow_migrate("db", "models_", "nonexistentmodel"))
18+
19+
def test_embedded_model(self):
20+
self.assertIs(self.router.allow_migrate("db", "models_", "embed"), False)

0 commit comments

Comments
 (0)