Миграции Django игнорируют db_table при установке с использованием метакласса - PullRequest
0 голосов
/ 30 июня 2018

Я использую метакласс, чтобы автоматически устанавливать имена таблиц БД модели Django из верблюжьего случая в имена, разделенные '_', например, MyGreatModel будет иметь имя таблицы, например appname_my_great_model вместо значения по умолчанию appname_mygreatmodel:

class PrettyModelBase(ModelBase):

    def __new__(cls, name, bases, attrs):
        super_new = ModelBase.__new__(cls, name, bases, attrs)
        module_name = camel_to_underscore(name)
        model_module = sys.modules[cls.__module__]

        app_label = super_new.__module__.split('.')[-2]
        db_table = '%s_%s' % (app_label, module_name)
        if not getattr(super_new._meta, 'proxy', False):
             super_new._meta.db_table = db_table

        return super_new


class BaseModel(models.Model):

    __metaclass__ = PrettyModelBase

    class Meta:
        abstract = True

class MyGreatModel(BaseModel):
    somefield = models.TextField(default="")

Однако миграция, похоже, не подхватывает это db_table имя. Если я запускаю makemigrations, то CreateModel не показывает db_table в options для этой модели. Если я жестко закодирую его в class Meta из MyGreatModel, тогда это произойдет. Более того, если я проверю, чтобы SQL запускался с python manage.py sqlmigrate..., то он показывает, что он создаст таблицу appname_mygreatmodel, а не имя таблицы с разделителями.

Однако, если я выполню эту миграцию и затем изучу модель в оболочке Django, то MyGreatModel._meta.db_table покажет my_great_model, как я и ожидал от моего метакласса. Если я вручную добавлю атрибут db_table в параметры миграции init 0001 для CreateModel, то все в порядке и для последующих миграций, но Django должен делать это автоматически, я думаю ...

Почему миграции Django не набирают db_table здесь?

Я использую Django==1.10.5.

Спасибо за любую помощь

1 Ответ

0 голосов
/ 27 июня 2019

Этот вопрос был вновь поднят в списке рассылки django-developers: https://groups.google.com/forum/#!msg/django-developers/ncMCwMF2J3g/V3guuDbJCwAJ

Миграции Django используют model._meta.original_attrs для определения определения мета-класса: https://github.com/django/django/blob/stable/2.2.x/django/db/migrations/state.py#L454

Таким образом, если вы динамически мутируете model._meta после создания, вам также необходимо соответствующим образом изменить его original_attrs диктовку. Я думаю, что это должно работать (не проверено).

...