在django中为每个模型设置db

chr*_*zer 16 python django

我一直在关注django的多db文档.我想把我的一些模型分成不同的数据库.但我真的只是希望这些模型始终存在于特定的数据库中.我不需要特殊的路由.编写独特的路由器只是为了说"模型A,B和C存在于数据库X中,模型D,E和F总是存在于数据库Y中".

是否有更简单的方法来设置这样的默认值?例如,作为模型元字段?

use*_*125 16

您可以通过向模型显示自定义属性来轻松完成此操作:

class A(models.Model):
    _DATABASE = "X"

class B(models.Model):
    _DATABASE = "Y"
...
Run Code Online (Sandbox Code Playgroud)

然后你需要添加路由器.下一个将通过_DATABASE字段选择数据库,而没有_DATABASE属性的模型将使用default数据库,也只允许default数据库关系:

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  
Run Code Online (Sandbox Code Playgroud)

最后一步是在settings.py中指定你的路由器:

DATABASE_ROUTERS = ['path.to.class.CustomRouter']
Run Code Online (Sandbox Code Playgroud)

如果你打算在非默认数据库中使用多对多关系,这个解决方案将不起作用,因为关系模型不会有"_DATABASE"属性,在这种情况下,最好model._meta.app_label在db_for_read中使用类似过滤条件的东西/ db_for_write

  • @JohnWoo最好返回None而不是显式'default',因为如果没有DB路由器找到匹配项,Django将回退到'default'.https://docs.djangoproject.com/en/dev/topics/db/multi-db/#automatic-database-routing"默认路由方案确保如果未指定数据库,则所有查询都将回退到默认值数据库." (5认同)

小智 5

没有任何Meta字段(在某些时候有一个但由于它引入的限制而被删除).您需要一个数据库路由器来控制哪些对象转到哪个数据库.在您的情况下,路由器应该很容易实现.