首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将数据库路由器添加到Django项目

如何将数据库路由器添加到Django项目
EN

Stack Overflow用户
提问于 2018-12-20 05:49:53
回答 3查看 9.3K关注 0票数 6

我在这里的topics/db/multi-db中遵循了关于如何在一个Django项目中处理多个数据库的说明。

我已经创建了所需的两个路由器。它们另存为./database_routers/Disourse.py和./database_routers/wordpress.py

./database_routers/Disourse.py的内容是

代码语言:javascript
复制
class DiscourseRouter:
    """
    A router to control all database operations on models in the
    discourse application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read discourse models go to discourse.
        """
        if model._meta.app_label == 'discourse':
            return 'discourse'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write discourse models go to discourse.
        """
        if model._meta.app_label == 'discourse':
            return 'discourse'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the discourse app is involved.
        """
        if obj1._meta.app_label == 'discourse' or \
           obj2._meta.app_label == 'discourse':
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the discourse app only appears in the 'discourse'
        database.
        """
        if app_label == 'discourse':
            return db == 'discourse'
        return None

./database_routers/wordpress.py的内容是

代码语言:javascript
复制
class WordpressRouter:
    """
    A router to control all database operations on models in the
    wordpress application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read wordpress models go to wordpress.
        """
        if model._meta.app_label == 'wordpress':
            return 'wordpress'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write wordpress models go to wordpress.
        """
        if model._meta.app_label == 'wordpress':
            return 'wordpress'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """
        Allow relations if a model in the wordpress app is involved.
        """
        if obj1._meta.app_label == 'wordpress' or \
           obj2._meta.app_label == 'wordpress':
           return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the wordpress app only appears in the 'wordpress'
        database.
        """
        if app_label == 'wordpress':
            return db == 'wordpress'
        return None

我创建了一个空的./database_routers/__init__.py文件

我在api/settings中设置的数据库路由器设置

代码语言:javascript
复制
DATABASE_ROUTERS = ['database_routers.DiscourseRouter', 'database_routers.WordpressRouter']

当我尝试使用shell和i查看项目时,

代码语言:javascript
复制
 ./manage.py shell_plus

我得到了

代码语言:javascript
复制
ImportError: Module "database_routers" does not define a "DiscourseRouter" attribute/class

如何将数据库路由器添加到Django项目中,使python能够识别路径directory_name.ClassName?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-12-20 06:34:00

您遗漏了模块名称。

代码语言:javascript
复制
DATABASE_ROUTERS = [
    'database_routers.discourse.DiscourseRouter', 
    'database_routers.wordpress.WordpressRouter'
]
票数 6
EN

Stack Overflow用户

发布于 2018-12-20 05:53:57

如果我很好地理解您,您打算配置多个数据库,对吗?请查看以下内容:

代码语言:javascript
复制
class ExampleDatabaseRouter(object):
    """
    Determine how to route database calls for an app's models (in this case, for an app named Example).
    All other models will be routed to the next router in the DATABASE_ROUTERS setting if applicable,
    or otherwise to the default database.
    """

    def db_for_read(self, model, **hints):
        """Send all read operations on Example app models to `example_db`."""
        if model._meta.app_label == 'example':
            return 'example_db'
        return None

    def db_for_write(self, model, **hints):
        """Send all write operations on Example app models to `example_db`."""
        if model._meta.app_label == 'example':
            return 'example_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """Determine if relationship is allowed between two objects."""

        # Allow any relation between two models that are both in the Example app.
        if obj1._meta.app_label == 'example' and obj2._meta.app_label == 'example':
            return True
        # No opinion if neither object is in the Example app (defer to default or other routers).
        elif 'example' not in [obj1._meta.app_label, obj2._meta.app_label]:
            return None

        # Block relationship if one object is in the Example app and the other isn't.
            return False

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """Ensure that the Example app's models get created on the right database."""
        if app_label == 'example':
            # The Example app should be migrated only on the example_db database.
            return db == 'example_db'
        elif db == 'example_db':
            # Ensure that all other apps don't get migrated on the example_db database.
            return False

        # No opinion for all other scenarios
        return None

您也可以从enter link description here阅读更多内容

票数 1
EN

Stack Overflow用户

发布于 2021-02-19 04:13:08

除了丹尼尔的回答之外,另一个给您更多控制权的选择是在__init__中声明您的类。

database_routers.__init__.py的内容

代码语言:javascript
复制
from .discourse.DiscourseRouter
from .wordpress.WordpressRouter


__all__ = [
    "DiscourseRouter",
    "WordpressRouter",
]

然后,这允许您删除settings.py中的模块名称

代码语言:javascript
复制
DATABASE_ROUTERS = [
    'database_routers.DiscourseRouter', 
    'database_routers.WordpressRouter'
]

换句话说,原始代码可以工作。

这将使您能够更好地控制哪些模块是公共的。

注意:这个__init__.py / __all__模式被广泛使用,例如:https://github.com/django/django/blob/master/django/db/.py

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53859629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档