首页 > 解决方案 > 在另一个数据库中验证用户 Django

问题描述

在同一个项目中,我有一些应用程序应该将数据存储在 localhost 数据库中,一些应用程序应该存储在远程数据库中。

我创建了一个routers.py文件并将其导入到我的settings.py. 我还在我的设置文件中定义了 2 个数据库。这是正确的吗?

在某些模型/类app_label = 'remote_db'上,我设置了需要将数据写入远程数据库的位置。

部分settings.py

DATABASES={
    'default':{
        ...
    },
    'remote_db':{
        ...
    }
}
DATABASE_ROUTERS = ['smart.routers.AccessRouter',]
AUTH_USER_MODEL = 'users.SmartUser'
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
)

部分users/models.py

class SmartUser(AbstractBaseUser, PermissionsMixin):
    class Meta:
        app_label = 'remote_db'

当我尝试时run makemigrations users,我收到以下错误:

AUTH_USER_MODEL 指的是尚未安装的模型 '%s'" % settings.AUTH_USER_MODEL django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL 指的是尚未安装的模型 'users.SmartUser'

标签: djangoauthentication

解决方案


如果您有将存在于其他地方的表/模型,您需要告诉 Django 它们不是托管模型。

像这样的东西在你的models.py

class SomeClass(models.Model):
    id = models.IntegerField(db_column="id", primary_key=True)
    ...other attributes...

    class Meta(object):
        db_table = "your_table_for_this_model"
        managed = getattr(settings, "UNDER_TEST", False) 

我使用一个名为“UNDER_TEST”的全局变量,以便在运行我们的测试时,django 将管理模型并创建测试表。如果您的数据库允许创建测试表,您可能不必这样做。我们的数据库受到严格管理,并且禁止创建测试表,因此我们使用这种解决方法来确保我们可以创建/运行测试以保持我们的代码被覆盖/测试。

在你的情况下,它只是一个User模型(我们也有它在一个单独的数据库中,它有自己的表),我们有这样的:

class User(AbstractUser):
...our attributes...

class Meta:
    db_table = "ourApp_user"

这就是我们User模型的专业内容。

在我们的设置中,我们与您相同,但我们不使用DATABASE_ROUTERS

AUTH_USER_MODEL = 'users.User'
AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
)

"default": {
    "ENGINE": "sql_server.pyodbc",
    "NAME": os.environ.get("default_NAME"),
    "HOST": os.environ.get("default_HOST"),
    "USER": os.environ.get("default_USER"),
    "PASSWORD": os.environ.get("default_PASSWORD"),
    "PORT": os.environ.get("default_PORT"),
    "OPTIONS": {
        "host_is_server": True,
        "driver": "ODBC Driver 13 for SQL Server",
    },
    "TEST": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": os.path.join(BASE_DIR, "default-db.sqlite3"),
    },
},
"other_db": {
    "ENGINE": "sql_server.pyodbc",
    "NAME": os.environ.get("other_db_NAME"),
    "HOST": os.environ.get("other_db_HOST"),
    "USER": os.environ.get("other_db_USER"),
    "PASSWORD": os.environ.get("other_db_PASSWORD"),
    "PORT": os.environ.get("other_db_PORT"),
    "OPTIONS": {
        "host_is_server": True,
        "driver": "ODBC Driver 13 for SQL Server",
    },
    "TEST": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": os.path.join(BASE_DIR, "other-db.sqlite3"),
    },
},

尝试删除app_label并放入db_table,或离开app_label并放入db_table以具体告诉它应该查看哪个表。

只有managed=False当它是一个表时,您将通过其他方式填充,并且如果您不希望 Django 管理其中的数据(例如:如果您有一个脚本生活在其他地方填充您的应用程序需要引用的特定表) .


推荐阅读