Django admin.site.register()方法溯源求助:新手开发者的困惑
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
siteis aLazyObject, it doesn't have aregistermethod of its own. Django'sLazyObjectuses the__getattr__magic method to catch this missing method call. __getattr__triggers the initialization of the wrapped object: it creates a real instance ofDefaultAdminSite.- The
registercall is then forwarded to this newly initializedDefaultAdminSiteinstance, which uses theregistermethod inherited fromAdminSite.
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




