外键默认值的 ValueError
ValueError on foreignkey default value
我删除了我的 db.sqlite3
和迁移文件夹中的文件,除了 __init__.py
但包括 __pycache__
文件夹。
我的应用程序的模型是一个文件夹中的多个文件,其中有一个 __init__.py
文件,其中包含一些导入和一个 __all__
变量(我不知道这是否重要)。
根据提示,我给出了第一个迁移命令,它看起来可以工作(迁移会话、管理员、身份验证、注册、内容类型。没有我的应用程序 'core')。
所以我给出了第一个 makemigrations 命令,然后又给出了 migrate 命令。
这次报错:
ValueError: invalid literal for int() with base 10: 'basic'
在模型中有一个外键字段,默认值为'basic'。 basic 将是相关 class 的一个对象,但实际上它并不存在(在我创建数据库之前,我将填充它)。我认为这很正常。
无论如何,我更改了 default=1 并且它起作用了(但是 1 不会是一个对象,所以它是错误的!)
我的model
:
Class Payment(models.Model):
name = models.CharField(max_length=32)
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default='basic', on_delete=models.PROTECT)
#etc
有没有办法使用'basic'?我宁愿不使用 id=1 因为我不确定 basic 将拥有的 id(记住现在它还不存在)。
顺便说一下,在其他模型中我有类似的情况并且它们似乎有效...
整个错误:
(myvenv) c:\Python34\Scripts\possedimenti\sitopossedimenti>manage.py migrate
Operations to perform:
Apply all migrations: contenttypes, core, registration, admin, auth, sessions
Running migrations:
Rendering model states... DONE
Applying core.0001_initial...Traceback (most recent call last):
File "C:\Python34\Scripts\possedimenti\sitopossedimenti\manage.py", line 10, i
n <module>
execute_from_command_line(sys.argv)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\__init__.py", line 353, in execute_from_command_line
utility.execute()
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\base.py", line 399, in execute
output = self.handle(*args, **options)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\commands\migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_ini
tial)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_
initial)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, projec
t_state)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\operations\fields.py", line 62, in database_forwards
field,
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back
ends\sqlite3\schema.py", line 221, in add_field
self._remake_table(model, create_fields=[field])
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back
ends\sqlite3\schema.py", line 103, in _remake_table
self.effective_default(field)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back
ends\base\schema.py", line 210, in effective_default
default = field.get_db_prep_save(default, self.connection)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\related.py", line 912, in get_db_prep_save
return self.target_field.get_db_prep_save(value, connection=connection)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\__init__.py", line 728, in get_db_prep_save
prepared=False)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\__init__.py", line 968, in get_db_prep_value
value = self.get_prep_value(value)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\__init__.py", line 976, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'basic'
谢谢
PS:我正在使用 python 3.4 Django 1.9 Windows7
在您的 Payment
模型中,您没有明确指定主键。所以 django 会为你创建一个。它将是一个整数自增字段。
Class Payment(models.Model):
name = models.CharField(max_length=32)
现在当你将Payment
定义为ProfileUser
的外键时,django认为它应该是Payment
中的主键字段,应该用作参考。
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default='basic', on_delete=models.PROTECT)
#etc
为了强制执行此引用,付款字段必须是整数。而且您不能将 'basic' 插入整数字段。
一种解决方案是使用
ForeignKey.to_field 选项明确引用付款中的不同字段 class。
ForeignKey.to_field¶ The field on the related object that the relation
is to. By default, Django uses the primary key of the related object.
这样你的class就会变成
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default='basic', on_delete=models.PROTECT,
to_field = 'name' )
#etc
现在这里的payment字段变成了CharField。请注意,在大多数情况下,使用整数字段作为外键会更有效。
另一种可能性是您将 Payment
中的 name
字段定义为主键。
创建一个函数来 return id(将其放在 ProfileUser 定义之前)。
def get_basic_id():
payment = Payment.options.get(name='basic')
return payment.id
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default=get_basic_id(), on_delete=models.PROTECT)
尽管如果您不知道 'basic' 会有什么 ID,您确定它会在数据库中吗?解决此问题的一种方法是使用固定装置填充付款 table。
我删除了我的 db.sqlite3
和迁移文件夹中的文件,除了 __init__.py
但包括 __pycache__
文件夹。
我的应用程序的模型是一个文件夹中的多个文件,其中有一个 __init__.py
文件,其中包含一些导入和一个 __all__
变量(我不知道这是否重要)。
根据提示,我给出了第一个迁移命令,它看起来可以工作(迁移会话、管理员、身份验证、注册、内容类型。没有我的应用程序 'core')。
所以我给出了第一个 makemigrations 命令,然后又给出了 migrate 命令。 这次报错:
ValueError: invalid literal for int() with base 10: 'basic'
在模型中有一个外键字段,默认值为'basic'。 basic 将是相关 class 的一个对象,但实际上它并不存在(在我创建数据库之前,我将填充它)。我认为这很正常。
无论如何,我更改了 default=1 并且它起作用了(但是 1 不会是一个对象,所以它是错误的!)
我的model
:
Class Payment(models.Model):
name = models.CharField(max_length=32)
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default='basic', on_delete=models.PROTECT)
#etc
有没有办法使用'basic'?我宁愿不使用 id=1 因为我不确定 basic 将拥有的 id(记住现在它还不存在)。
顺便说一下,在其他模型中我有类似的情况并且它们似乎有效...
整个错误:
(myvenv) c:\Python34\Scripts\possedimenti\sitopossedimenti>manage.py migrate
Operations to perform:
Apply all migrations: contenttypes, core, registration, admin, auth, sessions
Running migrations:
Rendering model states... DONE
Applying core.0001_initial...Traceback (most recent call last):
File "C:\Python34\Scripts\possedimenti\sitopossedimenti\manage.py", line 10, i
n <module>
execute_from_command_line(sys.argv)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\__init__.py", line 353, in execute_from_command_line
utility.execute()
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\base.py", line 399, in execute
output = self.handle(*args, **options)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\core\ma
nagement\commands\migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_ini
tial)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_
initial)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, projec
t_state)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\migr
ations\operations\fields.py", line 62, in database_forwards
field,
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back
ends\sqlite3\schema.py", line 221, in add_field
self._remake_table(model, create_fields=[field])
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back
ends\sqlite3\schema.py", line 103, in _remake_table
self.effective_default(field)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\back
ends\base\schema.py", line 210, in effective_default
default = field.get_db_prep_save(default, self.connection)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\related.py", line 912, in get_db_prep_save
return self.target_field.get_db_prep_save(value, connection=connection)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\__init__.py", line 728, in get_db_prep_save
prepared=False)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\__init__.py", line 968, in get_db_prep_value
value = self.get_prep_value(value)
File "c:\Python34\Scripts\possedimenti\myvenv\lib\site-packages\django\db\mode
ls\fields\__init__.py", line 976, in get_prep_value
return int(value)
ValueError: invalid literal for int() with base 10: 'basic'
谢谢
PS:我正在使用 python 3.4 Django 1.9 Windows7
在您的 Payment
模型中,您没有明确指定主键。所以 django 会为你创建一个。它将是一个整数自增字段。
Class Payment(models.Model):
name = models.CharField(max_length=32)
现在当你将Payment
定义为ProfileUser
的外键时,django认为它应该是Payment
中的主键字段,应该用作参考。
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default='basic', on_delete=models.PROTECT)
#etc
为了强制执行此引用,付款字段必须是整数。而且您不能将 'basic' 插入整数字段。
一种解决方案是使用 ForeignKey.to_field 选项明确引用付款中的不同字段 class。
ForeignKey.to_field¶ The field on the related object that the relation is to. By default, Django uses the primary key of the related object.
这样你的class就会变成
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default='basic', on_delete=models.PROTECT,
to_field = 'name' )
#etc
现在这里的payment字段变成了CharField。请注意,在大多数情况下,使用整数字段作为外键会更有效。
另一种可能性是您将 Payment
中的 name
字段定义为主键。
创建一个函数来 return id(将其放在 ProfileUser 定义之前)。
def get_basic_id():
payment = Payment.options.get(name='basic')
return payment.id
Class ProfileUser(models.Model):
payment = models.ForeignKey(Payment, blank=True, null=True,
default=get_basic_id(), on_delete=models.PROTECT)
尽管如果您不知道 'basic' 会有什么 ID,您确定它会在数据库中吗?解决此问题的一种方法是使用固定装置填充付款 table。