[Fixed]-Determine if an attribute is a `DeferredAttribute` in django


Here is how to check if a field is deferred:

from django.db.models.query_utils import DeferredAttribute

is_deferred = isinstance(model_instance.__class__.__dict__.get(field.attname), DeferredAttribute):

Taken from: https://github.com/django/django/blob/1.9.4/django/db/models/base.py#L393



This will check if the attribute is a deferred attribute and is not yet loaded from the database:

fks = dict((f, getattr(self, f.attname)) for f in self._meta.fields
                if (isinstance(f, models.ForeignKey) and f.attname in self.__dict__))

Internally, type(self) is a newly created Proxy model for the original class. A DeferredAttribute first checks the local dict of the instance. If that doesn’t exist, it will load the value from the database. This method bypasses the DeferredAttribute object descriptor so the value won’t be loaded if it doesn’t exist.

This works in Django 1.4 and 1.7, and presumably in the versions in between. Note that Django 1.8 will in due time introduce the get_deferred_fields() method which will supersede all this meddling with class internals.


Leave a comment