简体   繁体   English

为多个数据库使用多个Django管理站点

[英]Using multiple Django admin sites for multiple databases

I need to manage multiple databases within Django Admin. 我需要在Django Admin中管理多个数据库。 My two databases named 'local' and 'server' are defined in the settings file. 我的两个名为“local”和“server”的数据库在设置文件中定义。 Since Django doesn't allow to add several times the same model with different ModelAdmin , I am creating two instances of admin.AdminSite . 由于Django不允许使用不同的ModelAdmin多次添加相同的模型,因此我创建了两个admin.AdminSite实例。

Here is the code of the admin.py file: 这是admin.py文件的代码:

from core.models import MyModel

from django.contrib import admin

server_site = admin.AdminSite('server')
local_site = admin.AdminSite('local')


class MultiDBModelAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # Tell Django to save objects to the 'other' database.
        obj.save(using=self.using)

    def delete_model(self, request, obj):
        # Tell Django to delete objects from the 'other' database
        obj.delete(using=self.using)

    def get_queryset(self, request):
        # Tell Django to look for objects on the 'other' database.
        return super(MultiDBModelAdmin1, self).get_queryset(request).using(self.using)

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        # Tell Django to populate ForeignKey widgets using a query
        # on the 'other' database.
        return super(MultiDBModelAdmin1, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)

    def formfield_for_manytomany(self, db_field, request=None, **kwargs):
        # Tell Django to populate ManyToMany widgets using a query
        # on the 'other' database.
        return super(MultiDBModelAdmin1, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)


class MultiDBModelAdmin1(MultiDBModelAdmin):
    # A handy constant for the name of the alternate database.
    using = 'server'


class MultiDBModelAdmin2(MultiDBModelAdmin):
    # A handy constant for the name of the alternate database.
    using = 'local'


local_site.register(MyModel, MultiDBModelAdmin1)

server_site.register(MyModel, MultiDBModelAdmin2)

and here is the urls.py file: 这是urls.py文件:

from django.conf.urls import patterns, include, url

from core.admin import local_site, server_site


urlpatterns = patterns('',
    url(r'^admin/', include(local_site.urls)),
    url(r'^serveradmin/', include(server_site.urls)),
            [...]
)

I can access the admin panel using both the admin/ and serveradmin/ URLs, however the content is the very same: the administration panel is using the 'local' database, regardless of the admin panel I access. 我可以使用admin/serveradmin/ URL访问管理面板,但内容完全相同:管理面板使用“本地”数据库,无论我访问哪个管理面板。 How come Django doesn't discriminate the two? 为什么Django不歧视这两个?

You can override the get_queryset method and use a filter to allow switching the model list page on the admin from one db to the other: 您可以覆盖get_queryset方法并使用过滤器来允许将admin上的模型列表页面从一个db切换到另一个db:

class MultiDBListFilter(admin.SimpleListFilter):
    title = 'database'
    parameter_name = 'db'

    def lookups(self, request, model_admin):
        return tuple((db, db) for db in ['default'])

    def value(self):
        return super(MultiDBListFilter, self).value() or 'default'

    def queryset(self, request, queryset):
        return queryset

    def choices(self, cl):
        choices = super(MultiDBListFilter, self).choices(cl)
        choices.next()  # Skip `All` choice.
        for choice in choices:
            yield choice

class MyModelAdmin(admin.ModelAdmin):
    model = MyModel
    list_filter = (MultiDBListFilter, )

    def get_queryset(self, request):
        db = request.GET.get('db', 'default')
        return super(MyModelAdmin, self).get_queryset(request).using(db)

@Zack4 I now have almost exactly the same code as you, but mine works. @Zack4我现在和你几乎完全一样的代码,但我的工作。

One questionable thing that I see is that--- whereas it will be deprecated in 1.7, I recall having read--- in 1.6.5 which I'm using it's still necessary to include the following in the url config: 我看到的一个值得怀疑的事情是 - 虽然它会在1.7中被弃用,但我记得在1.6.5中我已经阅读了 - 我正在使用它仍然需要在url配置中包含以下内容:

admin.autodiscover()

When I omit that I get a notice that I don't have permission to change anything... not the problem identified in the question but maybe something else is being done that avoids that problem and leaves the one that you have. 当我省略的时候,我得到一个通知,我没有权限改变任何东西......不是问题中发现的问题,而是可能正在做的其他事情,以避免这个问题,并留下你拥有的问题。

And what is "core.admin" in your url config? 什么是你的网址配置中的“core.admin”? There is no Django module of that name, according to the error message that I get when I try it. 根据我尝试时收到的错误消息,没有该名称的Django模块。 Is "core" the name of your project root directory? “核心”是项目根目录的名称吗? Maybe there is a conflict with Django's use of the word "core". 也许与Django使用“核心”这个词有冲突。

Finally, in my struggles to learn about multiple databases in the Django docs I have seen that there is a special significance to the first database in DATABASES in setting.py--- this is if you're not using database routers (you and I aren't). 最后,在我努力学习Django文档中的多个数据库时,我发现在setup.py中DATABASES中的第一个数据库有一个特殊的意义---如果你没有使用数据库路由器(你和我)都没有)。

I give my first database the name "subscriber" but in settings.py it's: 我给我的第一个数据库命名为“subscriber”但在settings.py中它是:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': os.path.join(BASE_DIR, 'subscriber.db'),   
        ....

Now if I try to change "default" to "subscriber" Django objects and says that I must have a "default" database. 现在,如果我尝试将“default”更改为“subscriber”Django对象,并说我必须有一个“默认”数据库。 That I have learned, while arguing a ticket on the documentation with a core developer, is because default is there to receive the auth model stuff and other admin-related models. 我已经了解到,虽然与核心开发人员争论文档的票证是因为默认是接收auth模型的东西和其他管理相关的模型。

That is, if you "python manage.py dbshell --database=default", and then type ".tables", you should see not only your tables for local (or maybe default is server in your case) but also various authentication and admin stuff. 也就是说,如果你“python manage.py dbshel​​l --database = default”,然后输入“.tables”,你不仅应该看到本地的表(或者你的情况下默认是服务器),还要看各种身份验证和管理员的东西 (Type ".quit" to quit.) (输入“.quit”退出。)

Now what happens if you do the same to the other database, --database=server (if that's the other database's key of DATABASES in settings.py)? 现在如果对其他数据库执行相同操作会发生什么情况--database = server(如果这是settings.py中其他数据库的DATABASES键)? The first time I set up my two databases I had simply run syncdb, but that put auth and adminstrative models in both databases. 我第一次设置我的两个数据库时,我只是运行了syncdb,但是在两个数据库中放置了auth和adminstrative模型。 I simply deleted those models from my second database. 我只是从第二个数据库中删除了那些模型。

Finally, it smells like a simple url routing problem. 最后,它闻起来像一个简单的URL路由问题。 Did you by any chance simplify your urls for the sake of appearance for this post, changing them in the process? 您是否有机会为了这篇文章的出现而简化您的网址,在此过程中更改它们? What you show looks right. 你展示的看起来是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM