move get_submodels into mapdata.utils.models
This commit is contained in:
parent
d9f7210460
commit
d5420e6d96
3 changed files with 33 additions and 34 deletions
|
@ -12,6 +12,7 @@ from django.utils.functional import cached_property
|
||||||
|
|
||||||
from c3nav.editor.forms import create_editor_form
|
from c3nav.editor.forms import create_editor_form
|
||||||
from c3nav.editor.utils import is_created_pk
|
from c3nav.editor.utils import is_created_pk
|
||||||
|
from c3nav.mapdata.utils.models import get_submodels
|
||||||
|
|
||||||
|
|
||||||
class BaseWrapper:
|
class BaseWrapper:
|
||||||
|
@ -130,30 +131,12 @@ class ModelWrapper(BaseWrapper):
|
||||||
"""
|
"""
|
||||||
return create_editor_form(self._obj)
|
return create_editor_form(self._obj)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_submodels(cls, model: models.Model) -> typing.List[typing.Type[models.Model]]:
|
|
||||||
"""
|
|
||||||
Get non-abstract submodels for a model including the model itself.
|
|
||||||
Result is cached.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return cls._submodels_by_model[model]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
all_models = model.__subclasses__()
|
|
||||||
result = []
|
|
||||||
if not model._meta.abstract:
|
|
||||||
result.append(model)
|
|
||||||
result.extend(chain(*(cls.get_submodels(model) for model in all_models)))
|
|
||||||
cls._submodels_by_model[model] = result
|
|
||||||
return result
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def _submodels(self):
|
def _submodels(self):
|
||||||
"""
|
"""
|
||||||
Get non-abstract submodels for this model including the model itself.
|
Get non-abstract submodels for this model including the model itself.
|
||||||
"""
|
"""
|
||||||
return self.get_submodels(self._obj)
|
return get_submodels(self._obj)
|
||||||
|
|
||||||
def create_wrapped_model_class(self) -> typing.Type['ModelInstanceWrapper']:
|
def create_wrapped_model_class(self) -> typing.Type['ModelInstanceWrapper']:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,25 +1,16 @@
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.core.exceptions import FieldDoesNotExist
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
from django.db import models
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from c3nav.mapdata.utils.models import get_submodels
|
||||||
|
|
||||||
|
|
||||||
class MapdataConfig(AppConfig):
|
class MapdataConfig(AppConfig):
|
||||||
name = 'c3nav.mapdata'
|
name = 'c3nav.mapdata'
|
||||||
|
|
||||||
def _get_submodels(self, cls: type) -> List[models.Model]:
|
|
||||||
submodels = []
|
|
||||||
for subcls in cls.__subclasses__():
|
|
||||||
if issubclass(subcls, models.Model) and not subcls._meta.abstract:
|
|
||||||
submodels.append(subcls)
|
|
||||||
submodels.extend(self._get_submodels(subcls))
|
|
||||||
return submodels
|
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from c3nav.mapdata.models.geometry.base import GeometryMixin, GEOMETRY_MODELS
|
from c3nav.mapdata.models.geometry.base import GeometryMixin, GEOMETRY_MODELS
|
||||||
for cls in self._get_submodels(GeometryMixin):
|
for cls in get_submodels(GeometryMixin):
|
||||||
GEOMETRY_MODELS[cls.__name__] = cls
|
GEOMETRY_MODELS[cls.__name__] = cls
|
||||||
try:
|
try:
|
||||||
cls._meta.get_field('geometry')
|
cls._meta.get_field('geometry')
|
||||||
|
@ -27,10 +18,10 @@ class MapdataConfig(AppConfig):
|
||||||
raise TypeError(_('Model %s has GeometryMixin as base class but has no geometry field.') % cls)
|
raise TypeError(_('Model %s has GeometryMixin as base class but has no geometry field.') % cls)
|
||||||
|
|
||||||
from c3nav.mapdata.models.locations import Location, LOCATION_MODELS
|
from c3nav.mapdata.models.locations import Location, LOCATION_MODELS
|
||||||
LOCATION_MODELS.extend(self._get_submodels(Location))
|
LOCATION_MODELS.extend(get_submodels(Location))
|
||||||
|
|
||||||
from c3nav.mapdata.models.geometry.level import LevelGeometryMixin, LEVEL_MODELS
|
from c3nav.mapdata.models.geometry.level import LevelGeometryMixin, LEVEL_MODELS
|
||||||
LEVEL_MODELS.extend(self._get_submodels(LevelGeometryMixin))
|
LEVEL_MODELS.extend(get_submodels(LevelGeometryMixin))
|
||||||
|
|
||||||
from c3nav.mapdata.models.geometry.space import SpaceGeometryMixin, SPACE_MODELS
|
from c3nav.mapdata.models.geometry.space import SpaceGeometryMixin, SPACE_MODELS
|
||||||
SPACE_MODELS.extend(self._get_submodels(SpaceGeometryMixin))
|
SPACE_MODELS.extend(get_submodels(SpaceGeometryMixin))
|
||||||
|
|
25
src/c3nav/mapdata/utils/models.py
Normal file
25
src/c3nav/mapdata/utils/models.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from celery import chain
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
_submodels_by_model = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_submodels(model: typing.Type[models.Model]) -> typing.List[typing.Type[models.Model]]:
|
||||||
|
"""
|
||||||
|
Get non-abstract submodels for a model including the model itself.
|
||||||
|
Result is cached.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return _submodels_by_model[model]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
all_models = model.__subclasses__()
|
||||||
|
result = []
|
||||||
|
if not model._meta.abstract:
|
||||||
|
result.append(model)
|
||||||
|
result.extend(chain(*(get_submodels(model) for model in all_models)))
|
||||||
|
_submodels_by_model[model] = result
|
||||||
|
return result
|
Loading…
Add table
Add a link
Reference in a new issue