Django - how to specify a database for a model?

只愿长相守 提交于 2019-11-27 21:10:42
Horst Gutmann

As far as I know you can't specify the database directly with the model since it would kind of prevent the app from ever being reusable, but from what I can see in the docs:

https://docs.djangoproject.com/en/1.8/topics/db/multi-db/

Juan José Brown

You can't specify a database for a model, but you can define it in a custom DB router class.

# app/models.py
class SomeModel(models.Model):
    ...

# app/dbrouters.py
from app.models import SomeModel
...
class MyDBRouter(object):

    def db_for_read(self, model, **hints):
        """ reading SomeModel from otherdb """
        if model == SomeModel:
            return 'otherdb'
        return None

    def db_for_write(self, model, **hints):
        """ writing SomeModel to otherdb """
        if model == SomeModel:
            return 'otherdb'
        return None


# app/settings.py
DATABASE_ROUTERS = ('app.dbrouters.MyDBRouter',)
...
DATABASES = {
    ...
    'otherdb': {
        ....
    }
}

I found that you can route models pretty simply with this manager:

class SecondDbManager(models.Manager):
    def get_queryset(self):
        qs = super().get_queryset()

        # if `use_db` is set on model use that for choosing the DB
        if hasattr(self.model, 'use_db'):
            qs = qs.using(self.model.use_db)

        return qs

Just add use_db='databasename' and this manager to your model and it works.

Or to further simplify it I created a base model for it:

class SecondDbBase(models.Model):
    use_db = 'my_second_db'

    objects = SecureDbManager()

    class Meta:
        abstract = True

And with this all you need to do is extend it like so. Instead of:

class Customer(models.Model):

Just do this and it works:

class Customer(SecondDbBase):

PS. I'm not sure if it's a good practice or the best solution but it works and routing to other databases is a breeze :)

PSS. I've only ever used these for only reading and writing tables that are not managed by Django(managed = False) so if you need to create migrations for them, I'm not sure if it works or not. Might still need to use DATABASE_ROUTERS for that.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!