4

我在 Django 1.2 管理员中遇到了这个错误。

设想:

我有两个应用程序,比如说app1app2我的项目中。在这两个应用程序中,我定义了它们各自的admin.py文件以将每个应用程序各自的模型挂接到 django 的管理站点。

app1admin.py 中,我定义了三个 ModelAdmin 类,对应 app1 中的三个模型类,并将其中两个注册到管理站点。

class App11stModelAdmin (admin.ModelAdmin):
    #class definitions here

    #This class is an abstract class
    #class Meta:
    #   abstract = True

class App12ndModelAdmin (admin.ModelAdmin):
    #class definitions here

class App13rdModelAdmin (admin.ModelAdmin):
    #class definitions here

#register to admin site two of them
admin.site.register(App12ndModel, App12ndModelAdmin)
admin.site.register(App13rdModel, App13rdModelAdmin)

在里面app2,我导入app1.App11stModelAdmin来定义一个模型的管理app2模型。

在 admin.py 内部app2

from app1.admin import App11stModelAdmin

class App21stModelAdmin(App11stModelAdmin):
    #define some things here

#register App21stModelAdmin to admin site
admin.site.register(App21stModel, App21stModelAdmin)

使用此代码,我收到此错误消息:

AlreadyRegistered at /admin/

The model App12ndModel is already registered

Request Method:     GET
Request URL:    http://127.0.0.1:8000/admin/
Django Version:     1.2
Exception Type:     AlreadyRegistered
Exception Value:    

The model App12ndModel is already registered

这很奇怪,因为我确定我只注册了该模型的管理员一次。当我注释掉该模型的注册语句时,我得到了同样的错误,但现在是App13rdModel模型。

同时,为了解决这个问题,我删除了注册语句,而是将它们放在app1admin.py 中的“静态”函数中。

比如:在 app1 admin.py 里面

def register():
    admin.site.register(App12ndModel, App12ndModelAdmin)
    admin.site.register(App13rdModel, App13rdModelAdmin)

然后在 app2 admin.py

我在导入中包含了注册功能:

from app1.model import App11stModelAdmin, register

 ......
 ......
#register the two admin model in app1 inside app2 admin.py by calling the register function
register()

这有效。我不再收到“已注册”错误。

问题:

我做了什么导致该错误?我是 Django 和 Python 的新手。

非常感谢你!

4

2 回答 2

5

admin.py文件在运行时由 Django 执行,所以如果你将一个admin.py脚本导入另一个脚本,你实际上是在admin.site.register再次执行暴露的函数,从而给你Already Registered错误。

这实际上是标准的 Python 行为。考虑以下脚本(另存为sample.py):

def multiplier(x,y):
    return x*y

def sample_write(text):
    out = open("out.txt","w")
    out.write(text)
    out.close()

sample_write("hey") # Notice this executed function

当您在同一目录中打开 Python 解释器并执行此操作import sample时,它将写入out.txt输出。同样的情况下,当您有选择地导入multiplier类似的函数时from sample import multiplier,仍然会写入输出文件。避免写入输出文件的唯一方法是注释掉脚本中执行的函数或将其包装到另一个函数中。

于 2012-06-11T21:52:42.090 回答
3

唯一可能导致这种情况的是,如果您的 admin.py 是以两种不同的方式导入的。例如,以下被视为两个不同的模块,实际上会导致 admin.py 代码运行两次:

from foo.admin import FooAdmin
from myproject.foo.admin import FooAdmin
于 2012-06-11T21:24:34.520 回答