I've been looking over django's multi-db docs. I'd like to break a few of my models out into a different db. But I really just want those models to ALWAYS live in a particular db. I don't need special routing. And writing unique routers just to say "Models A, B, and C live in database X, models D, E, and F always live in database Y".
Is there a simpler way to set defaults like this? For instance, as a model meta field?
Django's admin doesn't have any explicit support for multiple databases. If you want to provide an admin interface for a model on a database other than that specified by your router chain, you'll need to write custom ModelAdmin classes that will direct the admin to use a specific database for content.
clean() This method should be used to provide custom model validation and to modify attributes on your model if desired.
In Django, a model is a class which is used to contain essential fields and methods. Each model class maps to a single table in the database. Django Model is a subclass of django.
You can easily do this by appearing custom attribute to model:
class A(models.Model):
_DATABASE = "X"
class B(models.Model):
_DATABASE = "Y"
...
Then you need to add router. Next one will select database by _DATABASE field, and models without _DATABASE attribute will use default
database, also relationships will be allowed only for default
database:
class CustomRouter(object):
def db_for_read(self, model, **hints):
return getattr(model, "_DATABASE", "default")
def db_for_write(self, model, **hints):
return getattr(model, "_DATABASE", "default")
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the master/slave pool.
"""
db_list = ('default')
return obj1._state.db in db_list and obj2._state.db in db_list
def allow_migrate(self, db, model):
"""
All non-auth models end up in this pool.
"""
return True
And the last step is specifing your router in settings.py:
DATABASE_ROUTERS = ['path.to.class.CustomRouter']
Source
BTW this solution will not work if you are going to work with many-to-many relations in non-default database because relational models will not have "_DATABASE", attribute, in this case, better to use something like model._meta.app_label
as filter condition in db_for_read/db_for_write
There is no Meta
field for this (there was one at some point but it got removed because of the limitations it introduced). You need a database router to control which objects go to what database. In your case the router should be pretty easy to implement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With