N
N
NotProblem2017-04-07 21:40:41
Django
NotProblem, 2017-04-07 21:40:41

Update Django 1.5 1.8 BaseModel with __metaclass__?

Good afternoon! I'm trying to update the project from 1.5 to 1.8, the project has an application to the models of which is accessed through the midelware, Application with site settings, with on-the-fly replacement, it consists of models.py admin.py, in the model code:

# models.py 

#coding=utf-8

from django.db import models
from django.db.models.loading import get_model



class MetaSetting(models.base.ModelBase):

    """
    For easy to use settings(Setting model).
    Instead of Setting.objects.get(name='KEY'), you can use Setting.KEY
    """

    def __getattr__(cls, key):

        _model = get_model('options', 'Option')

        try:
            val = _model.objects.get(name=key).value
        except _model.DoesNotExist:
            val = None

        if isinstance(val, basestring):
            val = val.encode('utf-8')

        return val

    def set_value(self, key, value, value_type=unicode):

        """
        key = key,
        value = value,
        value_type accept following values:
                unicode
                int
                float

        value_type default - basestring
        """

        _model = get_model('options', 'Option')

        if _model.objects.filter(name=key).exists():
            _model.objects.filter(name=key).update(val=value)

        else:
            _model.objects.create(name=key, val=value,
                                  value_type=Option.VALUE_TYPE_MAPPING.get(value_type))


class Option(models.Model):

    """
    Simple project settings
    """

    __metaclass__ = MetaSetting

    class Meta:
        verbose_name = u'Настройка'
        verbose_name_plural = u'Настройки'
        db_table = 'settings_setting'

    VALUE_TYPE_CHOICES = (
        (1, u'Строка',),
        (2, u'Целое',),
        (3, u'Вещественное',),
        # (4, u'Булево',),
    )

    VALUE_TYPE_MAPPING = {float: 3, int: 2, unicode: 1}

    VALUE_TYPE_CONVERTER = {
        1: lambda x: unicode(x),
        2: lambda x: int(x),
        3: lambda x: float(x),
        # 4: lambda x: bool(x),
    }

    name = models.CharField(u'Ключ', max_length=100, unique=True)
    val = models.TextField(u'Значение')
    value_type = models.PositiveSmallIntegerField(u'Тип значения', choices=VALUE_TYPE_CHOICES)

    @property
    def value(self):

        return self.VALUE_TYPE_CONVERTER[self.value_type](self.val)

in settings.INSTALL_APPS [
...
'app.options',
...
When updating according to the update logic, djangi added apps.py:
#coding=utf-8
from __future__ import unicode_literals

from django.apps import AppConfig


class OptionsConfig(AppConfig):
    name = 'app.options'

    def ready(self):
        from app.options.models import Option

when run it comes out:
Traceback (most recent call last):
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 229, in wrapper
    fn(*args, **kwargs)
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 107, in inner_run
    autoreload.raise_last_exception()
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 252, in raise_last_exception
    six.reraise(*_exception)
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/utils/autoreload.py", line 229, in wrapper
    fn(*args, **kwargs)
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/apps/config.py", line 198, 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 "/home/dev/gitwork/encased/app/options/models.py", line 52, in <module>
    class Option(models.Model):
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/db/models/base.py", line 90, in __new__
    base_meta = getattr(new_class, '_meta', None)
  File "/home/dev/gitwork/encased/app/options/models.py", line 17, in __getattr__
    _model = get_model('options', 'Option')
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/apps/registry.py", line 199, in get_model
    self.check_models_ready()
  File "/home/dev/virtualenvs/encased16/local/lib/python2.7/site-packages/django/apps/registry.py", line 131, in check_models_ready
    raise AppRegistryNotReady("Models aren't loaded yet.")

As I understand it, the whole point is in the model in:
__metaclass__ = MetaSetting
in which the meta settings are taken from the BaseModel, how to make it work?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question