Фон
Мы работаем в Python3.4/Django1.8.4, и мы наблюдаем странное явление в отношении нашей модели user
и, в частности, поля timezone
этой модели.
Каждый раз, когда мы делаем миграции, новый файл миграции будет включать операцию для изменения указанного поля часового пояса, но все атрибуты, которые включены в операцию, уже установлены в те же самые значения, которые миграция пытается назначить
Есть 3 таких поля, и они:
1) default
- со значением "UTC"
2) max_length
- со значением 30
и
3) choices
- очень длинный массив кортежей, содержащий имена/значения часовых поясов.
Похоже:
choices=[('Africa/Abidjan', 'Africa/Abidjan'), ('Africa/Accra', 'Africa/Accra'), ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), ... ]
Операция миграции всегда хочет установить эти 3 свойства поля timezone
на те же 3 соответствующие значения, даже если они уже установлены в такие значения! Это по существу избыточная, бесполезная операция.
Иногда при запуске makemigrations
изменений в приложении не будет, кроме этого глупого поля!
Вопросы
1) Почему это происходит?
2) Как это предотвратить? Это раздражает, что приложение считает, что миграции необходимы, когда они не являются.
Дополнительная информация
В то время как те же 3 свойства поля всегда заданы одинаковыми значениями, порядок, который они отображаются в операции, кажется недетерминированным (вероятно, из-за того, что django использует неупорядоченные экземпляры dict
для хранения данных, которые используемый для генерации файла миграции).
Поле choices
, как мы его определяем в нашей модели, динамически генерируется при первом запуске приложения. Код (сгенерированный) выглядит следующим образом:
class MyUser(models.Model):
f_name = models.CharField(max_length=32398) # Gotta accomodate those crazy south-eastern names haha
l_name = models.CharField(max_length=94823)
# ...
# more fields and stuff etc.
# ...
time_zone = models.CharField(default="UTC", choices=TIMEZONE_CHOICES, max_length=30)
Важная часть состоит в том, что choices=TIMEZONE_CHOICES
, которая определена ранее как таковая:
import pytz
TIMEZONE_CHOICES = ()
for time_zone in pytz.common_timezones:
TIMEZONE_CHOICES += ((time_zone, time_zone),)
Просто включите эту информацию в случае, если она окажется релевантной.