Django 1.7: lazy evaluation to avoid "application registry not ready yet" in models.py

I have a request in the definition of a model method:

'content_type_id': ContentType.objects.get_for_model(model).pk,

      

https://github.com/seperman/django-tagging/blob/develop/tagging/models.py#L107

And it brings up "Application registry is not ready yet".

Putting a string inside another independent function doesn't help, as it still makes a call.

Django docs:

Executing database queries using the ORM during import in the modules also throws this exception. ORM cannot function correctly until all models are available.

How can I make it lazy by evaluating this line? I was thinking about manually caching the results in a file by running a control command. And then reading the cached result, but there should be a much better / cleaner solution (?)

./manage.py shell
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
  execute_from_command_line(sys.argv)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
  utility.execute()
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute
  django.setup()
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/__init__.py", line 21, in setup
  apps.populate(settings.INSTALLED_APPS)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
  app_config.import_models(all_models)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
  self.models_module = import_module(models_module_name)
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
  __import__(name)
File "/var/www/something.com/something/current/apps/riding/models.py", line 32, in <module>
  class RidingSection(CategoryBase):
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/mptt/models.py", line 244, in __new__
  cls = meta.register(cls)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/mptt/models.py", line 325, in register
  obj = getattr(cls, attr)
File "/var/www/something.com/something/current/apps/tagging/fields.py", line 54, in __get__
  return edit_string_for_tags(Tag.objects.usage_for_model(owner))
File "/var/www/something.com/something/current/apps/tagging/models.py", line 148, in usage_for_model
  usage = self.usage_for_queryset(queryset, counts, min_count)
File "/var/www/something.com/something/current/apps/tagging/models.py", line 185, in usage_for_queryset
  return self._get_usage(queryset.model, counts, min_count, extra_joins, extra_criteria, params)
File "/var/www/something.com/something/current/apps/tagging/models.py", line 107, in _get_usage
  'content_type_id': ContentType.objects.get_for_model(model).pk,
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/contrib/contenttypes/models.py", line 50, in get_for_model
  defaults={'name': smart_text(opts.verbose_name_raw)},
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/manager.py", line 92, in manager_method
  return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 422, in get_or_create
  return self.get(**lookup), False
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 345, in get
  clone = self.filter(*args, **kwargs)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 691, in filter
  return self._filter_or_exclude(False, *args, **kwargs)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/query.py", line 709, in _filter_or_exclude
  clone.query.add_q(Q(*args, **kwargs))
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1287, in add_q
  clause, require_inner = self._add_q(where_part, self.used_aliases)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1314, in _add_q
  current_negated=current_negated, connector=connector)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1138, in build_filter
  lookups, parts, reffed_aggregate = self.solve_lookup_type(arg)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1076, in solve_lookup_type
  _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/sql/query.py", line 1339, in names_to_path
  field, model, direct, m2m = opts.get_field_by_name(name)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/options.py", line 416, in get_field_by_name
  cache = self.init_name_map()
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/options.py", line 445, in init_name_map
  for f, model in self.get_all_related_m2m_objects_with_model():
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/options.py", line 563, in get_all_related_m2m_objects_with_model
  cache = self._fill_related_many_to_many_cache()
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/db/models/options.py", line 577, in _fill_related_many_to_many_cache
  for klass in self.apps.get_models():
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/utils/lru_cache.py", line 101, in wrapper
  result = user_function(*args, **kwds)
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/apps/registry.py", line 168, in get_models
  self.check_models_ready()
File "/var/www/something.com/something/shared/env/local/lib/python2.7/site-packages/django/apps/registry.py", line 131, in check_models_ready
  raise AppRegistryNotReady("Models aren't loaded yet.")

      

django.core.exceptions.AppRegistryNotReady: Models have not been loaded yet.

0


source to share


2 answers


django-tagging is a bit inconsiderate here.

TagField is a descriptor , that is, when accessed, YourModel.tags

it runs code that executes a database query.

It just so happens that django-mptt iterates over all the attributes of your MPTTModel classes at startup time (before the application cache has loaded), so it throws this exception.



I don't know how you could prevent this in django-tagging while saving the API ( YourModel.tags

must be getting tags from somewhere). Issues like these are probably the reason django-tagging is no longer supported.

However, I do maintain django-mptt and I did a workaround . If you switch to the main version of mptt, you should find it now.

+2


source


You call _get_usage

before the application is registered. Wherever you call it needs to be changed to the point where the app was configured. Basically, if you need a model during import, you should use ready () .

For example, if you have signals.py

, you can do:

# in apps.py
class SomeAppConfig(AppConfig):
    def ready(self):
        from . import signals

      



or in your case:

# in apps.py
class SomeAppConfig(AppConfig):
    def ready(self):
        mgr = TagManager()
        mgr._get_usage(#some_args)

      

As stated in the docs: ready() ... is called as soon as the registry is fully populated

0


source







All Articles