Source code for mezzanine.boot
"""
An app that is forced to the top of the list in ``INSTALLED_APPS``
for the purpose of hooking into Django's ``class_prepared`` signal
and adding custom fields as defined by the ``EXTRA_MODEL_FIELDS``
setting. Also patches ``django.contrib.admin.site`` to use
``LazyAdminSite`` that defers certains register/unregister calls
until ``admin.autodiscover`` to avoid some timing issues around
custom fields not being available when custom admin classes are
registered.
"""
from __future__ import unicode_literals
from collections import defaultdict
from django import VERSION as DJANGO_VERSION
from django.apps import apps
from django.conf import settings
from django.contrib import admin
from django.core.exceptions import ImproperlyConfigured
from django.db.models.signals import class_prepared
from mezzanine.boot.lazy_admin import LazyAdminSite
from mezzanine.utils.importing import import_dotted_path
[docs]def parse_field_path(field_path):
"""
Take a path to a field like "mezzanine.pages.models.Page.feature_image"
and return a model key, which is a tuple of the form ('pages', 'page'),
and a field name, e.g. "feature_image".
"""
model_path, field_name = field_path.rsplit(".", 1)
app_name, model_name = model_path.split('.models.')
_, app_label = app_name.rsplit('.', 1)
return (app_label, model_name.lower()), field_name
[docs]def import_field(field_classpath):
"""
Imports a field by its dotted class path, prepending "django.db.models"
to raw class names and raising an exception if the import fails.
"""
if '.' in field_classpath:
fully_qualified = field_classpath
else:
fully_qualified = "django.db.models.%s" % field_classpath
try:
return import_dotted_path(fully_qualified)
except ImportError:
raise ImproperlyConfigured("The EXTRA_MODEL_FIELDS setting contains "
"the field '%s' which could not be "
"imported." % field_classpath)
fields = parse_extra_model_fields(getattr(settings, "EXTRA_MODEL_FIELDS", []))
if DJANGO_VERSION < (1, 9):
if fields:
class_prepared.connect(add_extra_model_fields,
dispatch_uid="FQFEQ#rfq3r")
else:
for model_key in fields:
apps.lazy_model_operation(add_extra_model_fields, model_key)
# Override django.contrib.admin.site with LazyAdminSite. It must
# be bound to a separate name (admin_site) for access in autodiscover
# below.
admin_site = LazyAdminSite()
admin.site = admin_site
django_autodiscover = admin.autodiscover
[docs]def autodiscover(*args, **kwargs):
"""
Replaces django's original autodiscover to add a call to
LazyAdminSite's lazy_registration.
"""
django_autodiscover(*args, **kwargs)
admin_site.lazy_registration()
admin.autodiscover = autodiscover