django.core.exceptions.ValidationError值必须为十进制数字

时间:2019-06-28 14:50:54

标签: python django

因此,我有两种不同的django模型,我想根据条件在另一模型(配置为CharField)的一个字段中填充一些字符串,该字符串取决于条件。我为此写了一个简单的方法: method screenshot

    def detect_closing_reason(self):
        if self.recommendation.stoploss is None:
            return 'Non-recognized'
        else:
            return 'Closing by a stoploss'

在类的下一个方法中,我试图在创建和保存模型实例的内部调用此方法:model creating and saving

    def create_virtual_transaction(self):
        date = self.recommendation.posted_time
        posix_date = datetime.timestamp(date)
        vo = VirtualTransaction.objects.create(start_price=self.recommendation.buy_levels,
                                               start_date=posix_date,
                                               end_price=self.recommendation.sell_levels,
                                               end_date=None,
                                               is_closed=None,
                                               author=self.take_author(),
                                               stock=self.recommendation.stock,
                                               coin=self.recommendation.coin,
                                               closing_reason=self.detect_closing_reason()))
        vo.save()

通过django管理命令运行此命令时,我收到此错误:error screenshot

Traceback (most recent call last):
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 1554, in to_python
    return decimal.Decimal(value)
decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 21, in <module>
    main()
  File "manage.py", line 17, in main
    execute_from_command_line(sys.argv)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
    output = self.handle(*args, **options)
  File "/home/work/signals/trading_signals/parser/management/commands/add_virtual_transaction.py", line 21, in handle
    pc.create_virtual_transaction()
  File "/home/work/signals/trading_signals/parser/profit_analysis.py", line 57, in create_virtual_transaction
    closing_reason=self.detect_closing_reason())
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/query.py", line 422, in create
    obj.save(force_insert=True, using=self.db)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/base.py", line 741, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/base.py", line 779, in save_base
    force_update, using, update_fields,
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/base.py", line 870, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/base.py", line 908, in _do_insert
    using=using, raw=raw)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/query.py", line 1186, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1334, in execute_sql
    for sql, params in self.as_sql():
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1278, in as_sql
    for obj in self.query.objs
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1278, in <listcomp>
    for obj in self.query.objs
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1277, in <listcomp>
    [self.prepare_value(field, self.pre_save_val(field, obj)) for field in fields]
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/sql/compiler.py", line 1218, in prepare_value
    value = field.get_db_prep_save(value, connection=self.connection)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 1563, in get_db_prep_save
    return connection.ops.adapt_decimalfield_value(self.to_python(value), self.max_digits, self.decimal_places)
  File "/home/work/.local/share/virtualenvs/signals-3Fvtwo2f/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 1559, in to_python
    params={'value': value},
django.core.exceptions.ValidationError: ["'[]' value must be a decimal number."]

两个字段(首先在第一个屏幕截图中使用一种方法从另一个模型中获取,第二个我试图将其保存在数据库中)配置为CharField:first field second field

class TelegramRecommendation(models.Model):
    channel_name = models.CharField(max_length=2000, blank=True, null=True)
    channel_forwarded_name = models.CharField(max_length=2000, blank=True, null=True)
    stock = models.CharField(max_length=2000, blank=True, null=True)
    coin = models.CharField(max_length=2000, blank=True, null=True)
    message = models.TextField(blank=True, null=True)
    buy_levels = models.CharField(max_length=2000, blank=True, null=True)
    sell_levels = models.CharField(max_length=2000, blank=True, null=True)
    posted_time = models.DateTimeField(default=None)
    stoploss = models.CharField(max_length=2000, blank=True, null=True)

    class Meta:
        ordering = ('channel_forwarded_name', 'posted_time')


class VirtualTransaction(models.Model):
    author = models.ForeignKey(Recommender, on_delete=models.CASCADE)
    stock = models.CharField(max_length=2000, blank=True, null=True)
    coin = models.CharField(max_length=2000, blank=True, null=True)
    start_date = models.CharField(max_length=2000, blank=True, null=True)
    end_date = models.CharField(max_length=2000, blank=True, null=True)
    start_price = models.DecimalField(max_digits=16, decimal_places=8, blank=True, null=True)
    end_price = models.DecimalField(max_digits=16, decimal_places=8, blank=True, null=True)
    is_closed = models.CharField(max_length=2000, blank=True, null=True)
    closing_reason = models.CharField(max_length=2000, blank=True, null=True)

我曾尝试重置迁移并删除并创建一个数据库(PostgreSQL 11.4),但并没有帮助。 my 0001_initial.py migration

migrations.CreateModel(
            name='TelegramRecommendation',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('channel_name', models.CharField(blank=True, max_length=2000)),
                ('channel_forwarded_name', models.CharField(blank=True, max_length=2000)),
                ('stock', models.CharField(blank=True, max_length=2000)),
                ('coin', models.CharField(blank=True, max_length=2000)),
                ('message', models.TextField(blank=True, null=True)),
                ('buy_levels', models.CharField(blank=True, max_length=2000)),
                ('sell_levels', models.CharField(blank=True, max_length=2000)),
                ('posted_time', models.DateTimeField(default=None)),
                ('stoploss', models.CharField(blank=True, max_length=2000)),
            ],
            options={
                'ordering': ('channel_forwarded_name', 'posted_time'),
            },
        ),
        migrations.CreateModel(
            name='VirtualTransaction',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('stock', models.CharField(blank=True, max_length=2000)),
                ('coin', models.CharField(blank=True, max_length=2000)),
                ('start_date', models.CharField(blank=True, max_length=2000)),
                ('end_date', models.CharField(blank=True, max_length=2000)),
                ('start_price', models.DecimalField(decimal_places=8, max_digits=16)),
                ('end_price', models.DecimalField(decimal_places=8, max_digits=16)),
                ('is_closed', models.CharField(blank=True, max_length=2000)),
                ('closing_reason', models.CharField(blank=True, max_length=2000)),
                ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='parser.Recommender')),

我的\ d +表名来自psql table information

我在这里找到了类似的问题,但没有任何帮助,我尝试过:重置迁移,将字符串转换为Decimal内置实例

我在django中没有太多经验,我可以犯一个愚蠢的错误,但是我已经花了大约12个小时来进行故障排除,所以我决定在这里写下一个问题。

1 个答案:

答案 0 :(得分:0)

该错误是由模型DecimalField中的2个VirtualTransactionstart_priceend_price)引起的。 看起来错误仅在self.detect_closing_reason()中,因为那是.objects.create()的最后一个参数;该错误实际上是由于DecimalField之一

CharField self.recommendation.buy_levelsself.recommendation.sell_levels之一的内容很可能无法转换为Decimal实例。

此外,在使用方法.objects.create()之后,如果您在.save()调用后未进行任何修改,则无需在返回的对象上调用.objects.create()

为了更容易发现错误,我建议将代码更改为此:

def create_virtual_transaction(self):
    date = self.recommendation.posted_time
    posix_date = datetime.timestamp(date)

    vo = VirtualTransaction()
    vo.start_price = self.recommendation.buy_levels
    vo.start_date = posix_date
    vo.end_price = self.recommendation.sell_levels
    vo.end_date = None
    vo.is_closed = None
    vo.author = self.take_author()
    vo.stock = self.recommendation.stock
    vo.coin = self.recommendation.coin
    vo.closing_reason = self.detect_closing_reason()
    vo.full_clean()
    vo.save()

注意对vo.full_clean()的呼叫;该行将引发一条更具体的错误消息,指出导致错误的字段。