You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Django admin.site.register()方法溯源求助:新手开发者的困惑

Understanding Django Admin's site.register() Method

Hey there! Let's break down this confusion step by step—digging into Django's internals is a great way to build a solid foundation, so kudos for going deep here.

1. The Role of LazyObject

First, let's clarify what LazyObject does. It's a proxy class from django.utils.functional designed to delay the initialization of the actual object until it's first used. This helps improve Django's startup performance by avoiding expensive setup work until it's absolutely necessary.

The site = DefaultAdminSite() you spotted in sites.py isn't directly a DefaultAdminSite instance right away—it's wrapped by LazyObject. That's why you don't see the register method on LazyObject itself: all method calls are forwarded to the underlying "wrapped" object once it's initialized.

2. Where the register Method Actually Lives

The register method is defined in the AdminSite class, which DefaultAdminSite inherits from (you'll find both classes in django/contrib/admin/sites.py). Here's a simplified snippet of that class:

class AdminSite:
    # ... other core admin logic ...
    def register(self, model_or_iterable, admin_class=None, **options):
        # Handles registering models, linking them to admin classes,
        # and updating the site's registry
        # ...

DefaultAdminSite is just a subclass that sets default configurations (like the site header and title), but it inherits all core functionality—including register—directly from AdminSite.

3. How the Lazy Loading Flow Works

When you call admin.site.register(Post) for the first time:

  • Since site is a LazyObject, it doesn't have a register method of its own. Django's LazyObject uses the __getattr__ magic method to catch this missing method call.
  • __getattr__ triggers the initialization of the wrapped object: it creates a real instance of DefaultAdminSite.
  • The register call is then forwarded to this newly initialized DefaultAdminSite instance, which uses the register method inherited from AdminSite.

4. The import * in admin/__init__.py

The from .sites import * line in django/contrib/admin/__init__.py is just a convenience: it makes the site instance (and other admin components) available directly under django.contrib.admin, so you can write from django.contrib import admin and access admin.site without importing the sites module explicitly.


内容的提问来源于stack exchange,提问作者ncwolf

火山引擎 最新活动