Имена моделей Django нечувствительны к регистру, верно?

Если у меня есть myapp/models.py

from django.db import models

class FooBar(models.Model):
    x = models.BooleanField()

class Foobar(models.Model):
    y = models.BooleanField()

и добавить myapp к INSTALLED_APPS и сделать syncdb, я получаю только модель FooBar, преобразованную в таблицу БД. Модель Foobar игнорируется.

Следует отметить еще одну странную вещь: когда мы делаем

from myapp import models

оба FooBar и Foobar присутствуют как атрибуты models. Однако,

>>> models.FooBar.__name__
'FooBar'
>>> models.Foobar.__name__
'FooBar'

и оба являются просто интерфейсами к таблице БД FooBar (по умолчанию myapp_foobar).

Я задаю этот вопрос, потому что мне кажется, что имена моделей django нечувствительны к регистру, и все же я не нашел никакой документации, в которой говорится об этом и, кроме того, на этот вопрос был дан ответ о том, что имена моделей django чувствительны к регистру.


person mjandrews    schedule 05.06.2014    source источник


Ответы (1)


Имена моделей Django не чувствительны к регистру, но в основном Django создает имя таблицы в нижнем регистре из имен приложения и модели. Таким образом, FooBar, который находится в myapp, сгенерирует таблицу myapp_foobar, и Foobar тоже.

Очевидно, что в вашем примере имена будут перекрываться. Django должен предупреждать о конфликтующих именах таблиц, но вместо этого молча игнорирует конфликтующие модели.

Чтобы исправить это, я предлагаю вам иметь явные и разные имена таблиц для ваших двух моделей. Используйте внутренний класс Meta и установите Meta.db_table. См. документацию Django по моделям Meta.

Дан пример:

class FooBar(models.Model):
    x = models.BooleanField()
    class Meta:
        db_table = 'myapp_foobar_one'

class Foobar(models.Model):
    x = models.BooleanField()
    class Meta:
        db_table = 'myapp_foobar_two'

В реальных условиях у меня никогда не было бы двух одинаковых названий моделей в одном приложении. Это чрезвычайно подвержено ошибкам.

person Steve K    schedule 06.06.2014
comment
Даже с вашим кодом в совершенно новом проекте проблема сохраняется. Foobar не ведет к новой таблице. Это просто игнорируется. Было бы разумно, если бы эта проблема была просто следствием имени таблицы по умолчанию (имя приложения плюс название модели версии в нижнем регистре), но похоже, что это кто-то другой. На практике я бы не стал использовать такие имена. Но меня смущает сам принцип. - person mjandrews; 06.06.2014
comment
Тогда это может быть связано с реестром приложений Django. На одной странице документации говорится, что возвращает модель с заданными app_label и model_name. Может быть, добавление разных app_label к метаклассам поможет? (не очень элегантно) - person Steve K; 06.06.2014
comment
Я думаю, что это может быть как-то связано с реестром приложений, как вы говорите. Вот мой лайфхак: я создал новое приложение под названием anotherapp, оставил models.py пустым и добавил его в INSTALLED_APPS. Теперь, если я поставлю app_label = 'anotherapp' в опции Meta для Foobar, то на syncdb я все-таки получу желаемое поведение, т.е. таблицы созданы и __name__ моделей правильные. - person mjandrews; 06.06.2014