Подтвердить что ты не робот

Django периодически обнаруживает избыточные миграции

Фон

Мы работаем в 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),)

Просто включите эту информацию в случае, если она окажется релевантной.

4b9b3361

Ответ 1

Вы можете попробовать использовать существующий пакет, который позволит вам использовать часовой пояс непосредственно в качестве поля модели.

https://pypi.python.org/pypi/django-timezone-field/

class MyModel(models.Model):
    timezone1 = TimeZoneField(default='Europe/London') # defaults supported

Ответ 2

Попробуйте скопировать обычный список часовых поясов от pytz к вашему проекту, поэтому вы уверены, что выбор не зависит от стороннего