关于 python:Django with Multiple Databases, Models from non-default Database Permissions in Admin

Django with Multiple Databases, Models from non-default Database Permissions in Admin

我有一个 Django 项目,它为所有 Django 设置了默认数据库,但还需要访问旧数据库。我在设置和数据库路由器中有这个工作。来自 Django 应用程序的模型对象本身会出现在管理中。但是,遗留数据库 Django 应用程序中的模型不会出现在管理员的权限部分下,我希望创建一个 Django 组,该组对这些模型/表具有权限,以便工作人员在查找表上执行 CRUD 功能。这是我的设置:

数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'mysite_classroom_d',
        'USER': 'mysite_classroom_user',
        'PASSWORD': '',
        'HOST': 'mysite-pg1.institution.edu',
        'PORT': '5432',
    },
    'mssqlmysite': {
        'ENGINE': 'sql_server.pyodbc',
        'HOST': 'sql14-dev.institution.edu',
        'PORT': '1433',
        'NAME': 'mysite',
        'USER': 'mysite_user',
        'PASSWORD': '',
        'AUTOCOMMIT': True,
        'OPTIONS': {
            'driver': 'FreeTDS',
            'autocommit': True,
            'unicode_results': True,
            'host_is_server': True,
            'extra_params': 'tds_version=7.2',
        },
    },
}

还有我的路由器;旧版 DB 应用程序称为 \\'formeditor\\':

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class FormEditorRouter(object):
   """
    A router to control all database operations on models in the
    formeditor application.
   """


    def db_for_read(self, model, **hints):
       """
        Attempts to read formeditor models go to mssqlmysite.
       """


        if model._meta.app_label == 'formeditor':
            return 'mssqlmysite'
        return None


    def db_for_write(self, model, **hints):
       """
        Attempts to write formeditor models go to mssqlmysite.
       """


        if model._meta.app_label == 'formeditor':
            return 'mssqlmysite'
        return None


    def allow_relation(self, obj1, obj2, **hints):
       """
        Allow relations if a model in the formeditor app is involved.
       """


        if obj1._meta.app_label == 'formeditor' or \\
           obj2._meta.app_label == 'formeditor':
           return True
        return None


    def allow_migrate(self, db, app_label, model=None, **hints):
       """
        Make sure the formeditor app only appears in the 'mssqlmysite'
        database.
       """


        if app_label == 'formeditor':
            return db == 'mssqlmysite'
        return None

还有一个示例模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
class DataCompanyMap(models.Model):
    vendor_id = models.IntegerField(blank=True, null=True)
    product_id = models.IntegerField(blank=True, null=True)
    file_id = models.IntegerField(blank=True, null=True)
    var_name = models.TextField(blank=True)
    common_var_name = models.TextField()
    searchable = models.NullBooleanField()
    example = models.TextField(blank=True)
    description = models.TextField(blank=True)

    class Meta:
        managed = False
        db_table = 'data_company_map'

我认为问题可能出在 managed = False 上,但即使将遗留数据库模型更改为 managed = True 也不会使其出现在 Django Admin 的权限部分。这里有什么想法吗?由于formeditor和admin在默认数据库中,Django Admin是否只能处理默认数据库中的模型?我已经谷歌并检查了 Django 文档,但似乎找不到明确的答案,我希望找到一个解决方案或我错过的明显的东西。提前感谢您抽出宝贵时间。


对我来说,我错过了 "in_db" 元参数,但也许你的路由器不是这样工作的。
还要确保将路由器指向设置 DATABASE_ROUTERS

对我有用的解决方案:

我的路由器:(来自:https://djangosnippets.org/snippets/2687/)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class ModelDatabaseRouter(object):
"""Allows each model to set its own destiny"""

def db_for_read(self, model, **hints):
    # Specify target database with field in_db in model's Meta class
    if hasattr(model._meta, 'in_db'):
        return model._meta.in_db
    return None

def db_for_write(self, model, **hints):
    # Specify target database with field in_db in model's Meta class
    if hasattr(model._meta, 'in_db'):
        return model._meta.in_db
    return None

def allow_syncdb(self, db, model):
    # Specify target database with field in_db in model's Meta class
    if hasattr(model._meta, 'in_db'):
        if model._meta.in_db == db:
            return True
        else:
            return False
    else:
        # Random models that don't specify a database can only go to 'default'
        if db == 'default':
            return True
        else:
            return False

在设置中添加:

1
DATABASE_ROUTERS = ['api.routers.ModelDatabaseRouter']

然后是模型:

1
2
3
4
5
6
class DataCompanyMap(models.Model):

    ..... The fields ....

    class Meta:
        in_db = 'mssqlmysite'