Почему я получаю ошибку при попытке добавить новый объект?
Я добавил поле, которое является внешним ключом, под названием user
в модель, но сначала я получил ошибку, которая гласила:
It is impossible to add a non-nullable field 'user' to bid without specifying a default.
Поэтому я сделал по умолчанию строку 'user'
. Однако вместо этого я получаю ошибку:
ValueError: invalid literal for int() with base 10: 'user'
когда я пытаюсь migrate
внести изменения, которые я сделал (python3 manage.py migrate
).
Когда я пытаюсь добавить новую ставку, я получаю ошибку на веб-странице:
OperationalError: no such column: auctions_listing.user_id
Как это исправить?
models.py:
class Bid(models.Model):
item = models.ForeignKey(Listing, on_delete=models.CASCADE)
price = models.FloatField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
Основная причина, по которой вы получаете ошибку, заключается в том, что вы предоставили строку в IntegerField
.
Настоящая причина вашей проблемы в том, что вы пытались запустить миграции с новым полем non-nullable без предоставления Django подходящего значения по умолчанию.
Когда вы запускаете миграции, Django необходимо заполнить новые поля существующих объектов чем-то, поскольку он не может ввести null. Вероятно, в терминале вас спросили, хотите ли вы указать значение по умолчанию, и вы ввели 'user', хотя нужно было целое число user_id (1, 2, 3 и т.д.).
Возможно, это не тот вариант, который вам нужен, поскольку в итоге вы назначите все существующие элементы одному конкретному пользователю. Ваше решение будет следующим:
- Удалите миграцию, которую вы пытались применить
- Разрешите полю быть nullable в вашем коде
- Запустите миграции
- Назначьте желаемых пользователей на каждый существующий объект
- Удалите
null=True
из поля - Запустите другую миграцию
Если не имеет значения, что определенному пользователю будут временно выделены все объекты, то вы можете пропустить шаг nullable и просто передать ID по умолчанию, когда вас спросят, и изменить их после выполнения миграции. Вы можете не делать этого, если это повлияет на текущих пользователей вашего приложения.
первая ошибка:
Невозможно добавить ненулевое поле 'user' к заявке, не указав его по умолчанию. без указания значения по умолчанию.
Вы столкнулись с этой ошибкой, потому что у вас уже есть некоторые записи в вашей базе данных и у них не было этого нового поля/колонки 'user', поэтому когда вы попытались добавить поле 'user' в эту таблицу, не имея null=Ture
для него, что-то вроде:
user = models.ForeignKey(User, null=True, Blank=True, on_delete=models.CASCADE)
Что произойдет со старыми записями? Потому что у них еще не было этого столбца, и вы не предоставили это новое поле/столбец как необязательное поле/столбец, поэтому вы должны предоставить значение по умолчанию для старой записи в потоке миграции.
вторая ошибка:
ValueError: недопустимый литерал для int() с основанием 10: 'user
По умолчанию Django ORM использует тип integer для поля id/pk в таблицах, поэтому, когда вы создаете внешний ключ в ваших таблицах, потому что он ссылается на целочисленное поле, поэтому он должен быть целым, как и id/pk, (вы можете установить пользовательский тип для ваших внешних ключей в таблицах Django, если хотите). Потому что вы предоставляете строку по умолчанию для существующих записей, поэтому вы ввели поврежденные данные в вашу таблицу
третья ошибка:
OperationalError: нет такой колонки: auctions_listing.user_id
Это произошло потому, что ваш поток миграции столкнулся с проблемами и Django не смог создать новую миграцию для вашей таблицы
Что вам следует делать: если существующие данные не важны для вас:
- усеките вашу базу данных/таблицу
- удалите миграции приложения
- создайте миграции снова
else:
- найдите существующие строки, для которых вы создали неправильное значение по умолчанию
- обновите их существующими идентификаторами пользователей (целочисленное значение) или добавьте целочисленное значение по умолчанию в поле вашей модели, которое ссылается на целевого пользователя, например .
user = models.ForeignKey(User, default=1, on_delete=models.CASCADE)