Django:使用注册了不同模型的 2 个不同的 AdminSite 实例

发布于 2024-10-08 18:53:29 字数 2761 浏览 0 评论 0 原文

除了通常的管理员之外,我想为非员工用户创建一个有限的管理员。该管理站点将有不同的注册 ModelAdmin

我在项目目录中创建了一个文件夹 /useradmin/ ,类似于 contrib/admin/_init_.py 我添加了一个 autodiscover() ,它将注册 useradmin.py 模块中定义的模型而不是 admin.py :

# useradmin/__init__.py
def autodiscover():
# Same as admin.autodiscover() but registers useradmin.py modules
...
for app in settings.INSTALLED_APPS:
    mod = import_module(app)
    try:
        before_import_registry = copy.copy(site._registry)
        import_module('%s.useradmin' % app)
    except:
        site._registry = before_import_registry
        if module_has_submodule(mod, 'useradmin'):
            raise

我还在 useradmin/ 下创建了 site.py 来覆盖类似于 contrib/admin/sites 的 AdminSite:

# useradmin/sites.py
class UserAdminSite(AdminSite):
    def has_permission(self, request):
        # Don't care if the user is staff
        return request.user.is_active

    def login(self, request):
        # Do the login stuff but don't care if the user is staff
        if request.user.is_authenticated():
            ...
        else:
            ...

site = UserAdminSite(name='useradmin')

在项目的 URL 中:

# urls.py
from django.contrib import admin
import useradmin

admin.autodiscover()
useradmin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
    (r'^useradmin/', include(useradmin.site.urls)),
)

我尝试在应用程序目录下的 admin.py 和 useradmin.py 模块中注册不同的模型:

# products/useradmin.py
import useradmin
class ProductAdmin(useradmin.ModelAdmin):
    pass
useradmin.site.register(Product, ProductAdmin)

但是在注册模型时在 useradmin.py 中,如 useradmin.site.register(Product, ProductAdmin) ,我得到 'module' object has no attribute 'ModelAdmin' 异常。虽然当我通过 shell 尝试这个时;

import useradmin
from useradmin import ModelAdmin

不会引发任何异常。

有什么想法可能是错的吗?

编辑:

我尝试采用@Luke的方式,并尽可能地将代码安排如下: (文件路径相对于项目根目录)

# admin.py
from django.contrib.admin import autodiscover
from django.contrib.admin.sites import AdminSite
user_site = AdminSite(name='useradmin')

# urls.py (does not even have url patterns; just calls autodiscover())
import admin
admin.autodiscover()

# products/admin.py
import admin
from products.models import Product
admin.user_site.register(Product)

因此,当 admin.user_site.register(Product) 时,我收到 AttributeError: 'module' object has no attribute 'user_site' > 在 products/admin.py 中被调用。

有什么想法吗?

解决方案:

我不知道是否有更好的方法,但是,将项目根目录中的admin.py重命名为useradmin.py并更新导入相应地解决了最后一种情况,即命名和导入冲突。

Apart from the usual admin, I want to create a limited admin for non-staff users. This admin site will have different registered ModelAdmins.

I created a folder /useradmin/ in my project directory and similar to contrib/admin/_init_.py I added an autodiscover() which will register models defined in useradmin.py modules instead of admin.py:

# useradmin/__init__.py
def autodiscover():
# Same as admin.autodiscover() but registers useradmin.py modules
...
for app in settings.INSTALLED_APPS:
    mod = import_module(app)
    try:
        before_import_registry = copy.copy(site._registry)
        import_module('%s.useradmin' % app)
    except:
        site._registry = before_import_registry
        if module_has_submodule(mod, 'useradmin'):
            raise

I also cretated sites.py under useradmin/ to override AdminSite similar to contrib/admin/sites:

# useradmin/sites.py
class UserAdminSite(AdminSite):
    def has_permission(self, request):
        # Don't care if the user is staff
        return request.user.is_active

    def login(self, request):
        # Do the login stuff but don't care if the user is staff
        if request.user.is_authenticated():
            ...
        else:
            ...

site = UserAdminSite(name='useradmin')

In the project's URLs:

# urls.py
from django.contrib import admin
import useradmin

admin.autodiscover()
useradmin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
    (r'^useradmin/', include(useradmin.site.urls)),
)

And I try to register different models in admin.py and useradmin.py modules under app directories:

# products/useradmin.py
import useradmin
class ProductAdmin(useradmin.ModelAdmin):
    pass
useradmin.site.register(Product, ProductAdmin)

But when registering models in useradmin.py like useradmin.site.register(Product, ProductAdmin), I get 'module' object has no attribute 'ModelAdmin' exception. Though when I try this via shell;

import useradmin
from useradmin import ModelAdmin

does not raise any exception.

Any ideas what might be wrong?

Edit:

I tried going the @Luke way and arranged the code as follows as minimal as possible:
(file paths are relative to the project root)

# admin.py
from django.contrib.admin import autodiscover
from django.contrib.admin.sites import AdminSite
user_site = AdminSite(name='useradmin')

# urls.py (does not even have url patterns; just calls autodiscover())
import admin
admin.autodiscover()

# products/admin.py
import admin
from products.models import Product
admin.user_site.register(Product)

As a result I get an AttributeError: 'module' object has no attribute 'user_site' when admin.user_site.register(Product) in products/admin.py is called.

Any ideas?

Solution:

I don't know if there are better ways but, renaming the admin.py in the project root to useradmin.py and updating the imports accordingly resolved the last case, which was a naming and import conflict.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情绪 2024-10-15 18:53:29

useradmin 是否定义了 ModelAdmin 类,还是从 contrib.admin 导入它?我在您提供的代码中没有看到设置该类的任何地方。

话虽这么说,有一个更简单的方法来做到这一点:只需初始化两个 AdminSites,然后将它们连接到您想要的 URL(您甚至可以将它们 在同一个 urlconf 中)。

Does useradmin have a ModelAdmin class defined, or do you import it from contrib.admin? I don't see anywhere in the code you supplied where that class gets set up.

That being said, there's a much easier way to do this: just initialize two AdminSites, and then wire them up to the URLs that you want (You can even put them in the same urlconf).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文