Как изменить тип поля в модели Django с существующими данными?

У меня есть следующее существующее поле twitter в расширенной модели UserProfile, и я хотел бы изменить тип поля с URLField на CharField с max_length равным 20. Когда я пытаюсь перенести изменение, я получаю ошибку django.db.utils.DataError: value too long for type character varying(20). Я не забочусь о существующих данных в этом поле и предпочитаю, чтобы при миграции они были пустыми, если есть существующие данные. Как я могу изменить тип поля и очистить существующие данные?

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.SET_NULL, null=True)

    # old field
    twitter = models.URLField(verbose_name="Twitter", blank=True)

    # new field
    # twitter = models.CharField(
    #     max_length=20, verbose_name="Twitter Username", null=True, blank=True
    # )

Приближение 1-го

Для того чтобы изменить тип и максимальную длину поля, которое должно знать самую длинную длину url в вашей базе данных. Если вы используете базу данных sqlite3, то выполните следующий запрос в вашем db_shell или sqlite3 shell или что там у вас есть.

SELECT MAX(LENGTH(column_name)) FROM table_name;

и затем установите max_length поля new в это значение.

Приближение 2-го

python manage.py shell

и тогда

# Import your model
profiles = UserProfile.objects.all()
max_length = 0
for userprofile in userprofiles:
    if len(userprofile.twitter) > max_length:
        max_length = len(userprofile.twitter)
print(max_length)

и затем установите max_length в значение, выведенное из приведенного выше кода.

Эта ошибка означает, что в этом столбце есть значения, длина которых превышает 20 символов.

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

UPDATE <table_name>
SET twitter = ""
WHERE LENGTH(twitter) > 20;

Затем вы можете запускать миграции.

Вернуться на верх