以下简单测试,
from django.test import TestCase
class TestSetup(TestCase):
def test_setUp(self):
pdb.set_trace()
# Code here deleted, it made no difference to the error.
抛出错误:
> Destroying old test database for alias 'default'... Traceback (most
> recent call last): File
> "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 1957, in get_prep_value
> return float(value) ValueError: could not convert string to float: ''
>
> The above exception was the direct cause of the following exception:
>
> Traceback (most recent call last): File "manage.py", line 22, in
> <module>
> main() File "manage.py", line 18, in main
> execute_from_command_line(sys.argv) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/__init__.py",
> line 442, in execute_from_command_line
> utility.execute() File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/__init__.py",
> line 436, in execute
> self.fetch_command(subcommand).run_from_argv(self.argv) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/commands/test.py",
> line 24, in run_from_argv
> super().run_from_argv(argv) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/base.py",
> line 412, in run_from_argv
> self.execute(*args, **cmd_options) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/base.py",
> line 458, in execute
> output = self.handle(*args, **options) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/commands/test.py",
> line 68, in handle
> failures = test_runner.run_tests(test_labels) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/test/runner.py",
> line 1054, in run_tests
> old_config = self.setup_databases( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/test/runner.py",
> line 950, in setup_databases
> return _setup_databases( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/test/utils.py",
> line 221, in setup_databases
> connection.creation.create_test_db( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/creation.py",
> line 78, in create_test_db
> call_command( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/__init__.py",
> line 194, in call_command
> return command.execute(*args, **defaults) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/base.py",
> line 458, in execute
> output = self.handle(*args, **options) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/base.py",
> line 106, in wrapper
> res = handle_func(*args, **kwargs) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/core/management/commands/migrate.py",
> line 356, in handle
> post_migrate_state = executor.migrate( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/migrations/executor.py",
> line 135, in migrate
> state = self._migrate_all_forwards( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/migrations/executor.py",
> line 167, in _migrate_all_forwards
> state = self.apply_migration( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/migrations/executor.py",
> line 252, in apply_migration
> state = migration.apply(state, schema_editor) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/migrations/migration.py",
> line 132, in apply
> operation.database_forwards( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/migrations/operations/fields.py",
> line 235, in database_forwards
> schema_editor.alter_field(from_model, from_field, to_field) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/schema.py",
> line 830, in alter_field
> self._alter_field( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/postgresql/schema.py",
> line 287, in _alter_field
> super()._alter_field( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/schema.py",
> line 1025, in _alter_field
> new_default = self.effective_default(new_field) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/schema.py",
> line 429, in effective_default
> return field.get_db_prep_save(self._effective_default(field), self.connection) File
> "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 954, in get_db_prep_save
> return self.get_db_prep_value(value, connection=connection, prepared=False) File
> "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 947, in get_db_prep_value
> value = self.get_prep_value(value) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 1959, in get_prep_value
> raise e.__class__( ValueError: Field 'amount' expected a number but got ''.
“金额”字段确实存在,但在未加载任何测试的模型中:
models.py
class Appointment(models.Model):
amount = models.FloatField(blank=True, default=0.0)
但为了防止在创建测试数据库的过程中实例化该模型,我将“default=0.0”迁移到“default='0.0'”(值周围的单引号)。同样的错误。
我还尝试使用 psql 手动删除 postgresql 测试数据库。
我正在开始测试
python manage.py test
还可以通过指定app_name:
python manage.py test giraffe
来自项目目录。
相关迁移,按顺序排列:
# Generated by Django 4.1.3 on 2023-01-10 22:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0014_appointment_notes'),
]
operations = [
migrations.AlterField(
model_name='appointment',
name='amount',
field=models.FloatField(blank=True, default=''),
),
]
和
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0015_alter_appointment_amount'),
]
operations = [
migrations.AlterField(
model_name='appointment',
name='amount',
field=models.FloatField(blank=True),
),
]
和
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0016_alter_appointment_amount'),
]
operations = [
migrations.AlterField(
model_name='appointment',
name='amount',
field=models.FloatField(blank=True, default=0.0),
),
]
以及一些与具有“金额”字段的模型相关的早期迁移,但该模型已被删除,但仍显示在测试数据库中。
...migrations.CreateModel(
name='UnreimbursedMileage',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('mileage_rate_category', models.CharField(choices=[('FB22a', 'Federal Business Rate, Qtr. 1&2 2022'), ('FB22b', 'Federal Business Rate, Qtr. 3&4, 2022'), ('FB23', 'Federal Business Rate 2023')], default='FB22a', max_length=5)),
('num_miles', models.FloatField(blank=True, default=0)),
('amount', models.FloatField(blank=True, null=True)),
('for_appointment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='giraffe.appointment')),
],
options={
'verbose_name_plural': 'Unreimbursed Mileage',
},
),
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0054_rename_to_do_next_time_todonexttime_and_more'),
]
operations = [
migrations.RemoveField(
model_name='unreimbursedmileage',
name='for_appointment',
),
migrations.DeleteModel(
name='Dummy',
),
migrations.DeleteModel(
name='UnreimbursedMileage',
),
]
回溯显示调用 alter_field 时会发生这种情况。
> line 235, in database_forwards
> schema_editor.alter_field(from_model, from_field, to_field) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/schema.py",
> line 830, in alter_field
> self._alter_field( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/postgresql/schema.py",
> line 287, in _alter_field
> super()._alter_field( File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/schema.py",
> line 1025, in _alter_field
> new_default = self.effective_default(new_field) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/backends/base/schema.py",
> line 429, in effective_default
> return field.get_db_prep_save(self._effective_default(field), self.connection) File
> "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 954, in get_db_prep_save
> return self.get_db_prep_value(value, connection=connection, prepared=False) File
> "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 947, in get_db_prep_value
> value = self.get_prep_value(value) File "/var/www/ptech/venv/lib/python3.8/site-packages/django/db/models/fields/__init__.py",
> line 1959, in get_prep_value
> raise e.__class__( ValueError: Field 'amount' expected a number but got ''.
这是
migrations.AlterField
对象初始化的一部分。因此,当您创建 models.py
对象时,错误不在您的 models.FloatField
中。当您尝试创建 migrations.AlterField
对象时,就会发生这种情况。
查看最后一行,看看到底出了什么问题。
ValueError: Field 'amount' expected a number but got ''
因此,当您创建 SQL 数据库时,您需要让字段的类型与您尝试使用的数据类型相匹配。当您创建
AlterField
对象时,您在数据库中为字段“金额”指定了一个字符串默认值。但它是一个FloatField
,所以我们需要一个浮动。
这是有问题的代码:
# Generated by Django 4.1.3 on 2023-01-10 22:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0014_appointment_notes'),
]
operations = [
migrations.AlterField(
model_name='appointment',
name='amount',
field=models.FloatField(blank=True, default=''),
),
]
“金额”字段默认为空字符串“”,就像错误所示。我们需要一个漂浮物。
# Generated by Django 4.1.3 on 2023-01-10 22:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0014_appointment_notes'),
]
operations = [
migrations.AlterField(
model_name='appointment',
name='amount',
field=models.FloatField(blank=True, default=0.0),
),
]
同样,所有
FloatField
对象在创建时都需要有一个默认的浮点值。 0014_appointment_notes
之后的下一次迁移,0015_alter_appointment_amount
没有任何FloatField
的默认值。将其更改为默认浮点值。
class Migration(migrations.Migration):
dependencies = [
('giraffe', '0015_alter_appointment_amount'),
]
operations = [
migrations.AlterField(
model_name='appointment',
name='amount',
field=models.FloatField(blank=True),
),
]
您可能尝试过改变这一点,但什么也没发生。
正如 Ron 在评论部分所说,解决方案是重置您的迁移。每个有 Django 应用程序的文件夹中都有一个隐藏文件夹,即每个文件夹都有自己的
models.py
。这是我们调用 makemigrations
之后创建的缓存文件,以加快 migrate
命令的速度,因为通常模型本身不会更改。添加新模型将更新此缓存,但更改模型则不会。确保使用 Unix 命令删除每个隐藏文件夹 .migrations
以及其中的所有文件和文件夹。
rm -r .migrations
运行
migrate
命令现在将自动运行命令 makemigrations
,因为 .migrations
文件夹不存在,现在必须创建才能迁移数据库。