Log in to see the middleware, it was found request.user returns SimpleOject objects, see the LazyObject turn down, look at the source code looked a long time did not understand
Internet search a pile of inert material under load to achieve it is to understand what function, to return to see the source code, probably know the principle LazyObject implementation
Django inert load is generated when the first object is not instantiated, until the property or method call the object when instantiated operations do
LazyObject Source:
= empty Object () # inert implemented method of loading generic class of methods, i.e., to see whether an object is instantiated # if not yet instantiated, the instance of a subclass of method invocation # last call the original method based on the instance func generated DEF new_method_proxy (FUNC): DEF Inner (Self, * args): IF self._wrapped IS empty: self._setup () return FUNC (self._wrapped, * args) return Inner class LazyObject: "" " A wrapper for Another class that CAN Used to Delay instantiation of BE at The wrapped class. By subclassing, you have have to Intercept and the ALTER at The Opportunity at The instantiation. the If you do not need to do that, use SimpleLazyObject. "" " #. The Avoid Infinite recursion When Tracing the __init__ (# 19456) _wrapped = None DEF the __init__ (Self): # Note: IF A subclass The overrides the __init __ (), IT Will LIKELY need to # the override __copy __ () and __deepcopy __ () AS Well. Self. empty = _wrapped # flag if there is instantiated __getattr__ = new_method_proxy (getattr) # calls generic instantiation delay method DEF __setattr__ (Self, name, value): iF name == " _wrapped " : # the Assign to __dict__ to Avoid __setattr__ Infinite Loops.When the changes are _wrapped, special handling # . Self the __dict__ [ " _wrapped " ] = value the else : IF self._wrapped IS empty: self._setup () setattr (self._wrapped, name, value) # instantiated, modified examples of attributes DEF __delattr__ (Self, name): IF name == " _wrapped " : # can not delete _wrapped property the raise (TypeError " . CAN not the delete _wrapped " ) IF self._wrapped is empty: self._setup() delattr(self._wrapped, name) def _setup(self): """ Must be implemented by subclasses to initialize the wrapped object. """ #只可由子类调用 raise NotImplementedError('subclasses of LazyObject must provide a _setup() method') # Because we have messed with __class__ below, we confuse pickle as to what # class we are pickling. We're going to have to initialize the wrapped # object to successfully pickle it, so we might as well just pickle the # wrapped object since they're supposed to act the same way. # # Unfortunately, if we try to simply act like the wrapped object, the ruse # will break down when pickle gets our id(). Thus we end up with pickle # thinking, in effect, that we are a distinct object from the wrapped # object, but with the same __dict__. This can cause problems (see #25389). # # So instead, we define our own __reduce__ method and custom unpickler. We # pickle the wrapped object as the unpickler's argument, so that pickle # will pickle it normally, and then the unpickler simply returns its # argument. def __reduce__(self): if self._wrapped is empty: self._setup() return (unpickle_lazyobject, (self._wrapped,)) def __copy__(self): if self._wrapped is empty: # If uninitialized, copy the wrapper. Use type(self), not # self.__class__, because the latter is proxied. return type(self)() else: # If initialized, return a copy of the wrapped object. return copy.copy(self._wrapped) def __deepcopy__(self, memo): if self._wrapped is empty: # We have to use type(self), not self.__class__, because the # latter is proxied. result = type(self)() memo[id(self)] = result return result return copy.deepcopy(self._wrapped, memo) __bytes__ = new_method_proxy(bytes) __str__ = new_method_proxy(str) __bool__ = new_method_proxy(bool) # Introspection support __dir__ = new_method_proxy(dir) # Need to pretend to be the wrapped class, for the sake of objects that # care about this (especially in equality tests) __class__ = property(new_method_proxy(operator.attrgetter("__class__"))) __eq__ = new_method_proxy(operator.eq) __lt__ = new_method_proxy(operator.lt) __gt__ = new_method_proxy(operator.gt) __ne__ = new_method_proxy(operator.ne) __hash__ = new_method_proxy(hash) # List/Tuple/Dictionary methods support __getitem__ = new_method_proxy(operator.getitem) __setitem__ = new_method_proxy(operator.setitem) __delitem__ = new_method_proxy(operator.delitem) __iter__ = new_method_proxy(iter) __len__ = new_method_proxy(len) __contains__ = new_method_proxy(operator.contains)