#python #python-3.x #django
#python #python-3.x #django
Вопрос:
Глядя на:
https://docs.djangoproject.com/en/3.1/ref/models/instances/#django.db.models .Model.save
Для удобства каждая модель по умолчанию имеет автоматическое поле с именем id, если вы явно не укажете primary_key=True в поле вашей модели. Более подробную информацию см. В документации для автозаполнения.
и
https://docs.djangoproject.com/en/3.1/topics/db/models/
кажется очевидным, что у объекта всегда есть идентификатор. У меня есть модель:
class Currency(models.Model):
currency_name = models.CharField(max_length=100)
currency_value_in_dollars = models.FloatField()
currency_value_in_dollars_date = models.DateField()
def __str__(self):
return self.currency_name
что я перенес как:
operations = [
migrations.CreateModel(
name='Currency',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('currency_name', models.CharField(max_length=100)),
('currency_value_in_dollars', models.FloatField()),
('currency_value_in_dollars_date', models.DateField()),
],
),
и при попытке добавить записи в БД, например:
def update_coins_table():
if not do_greeting():
print("Gecko crypto board not reachable. Db setup")
return
crypto_coins_prices = cg.get_price(ids=coins_ids_str, vs_currencies='usd')
timezone_now = timezone.now()
for coin_key in crypto_coins_prices:
coin = Currency(coin_key, crypto_coins_prices[coin_key]['usd'], timezone_now)
coin.save()
строка:
coin = Currency(coin_key, crypto_coins_prices[coin_key]['usd'], timezone_now)
дает:
unable to get repr for <class 'manage_crypto_currency.models.Transaction'>
и
coin.save()
сбой. Если я заменю рассматриваемую строку на:
coin = Currency(1, coin_key, crypto_coins_prices[coin_key]['usd'], timezone_now)
это работает. Разве идентификатор не должен автоматически увеличиваться?
Последняя строка всегда перезаписывает предыдущую, и в конце сохраняется только одна запись.
Ответ №1:
Первым позиционным параметром по-прежнему является id
. Является ли это AutoField
или нет, не имеет значения. Тем более, что Django также использует конструктор для загрузки объектов модели из базы данных, и иногда вы хотите указать идентификатор, потому что вы хотите обновить объект.
Вы можете использовать None
, если не хотите указывать первичный ключ:
# ↓ use None such that the database will provide an id
coin = Currency(None, coin_key, crypto_coins_prices[coin_key]['usd'], timezone_now)
но, несмотря на это, оно по-прежнему «нестабильно», поскольку добавление дополнительного поля где-либо приводит к тому, что порядок параметров изменится. Лучше использовать именованные параметры:
coin = Currency(
currency_name=coin_key,
currency_value_in_dollars=crypto_coins_prices[coin_key]['usd'],
currency_value_in_dollars_date=timezone_now
)
Примечание: у Django
DateTimeField
[Django-doc]
естьauto_now_add=…
параметр [Django-doc]
для работы с временными метками. Это автоматически назначит текущую дату
и время при создании объекта и пометит его как не редактируемый (editable=False
), так
что он не отображается вModelForm
s по умолчанию.
Комментарии:
1. Удалось сохранить записи; можно было бы сделать немного более интуитивно понятным