python - 外键默认值的 ValueError

标签 python django foreign-keys default-value

我删除了 db.sqlite3 以及迁移文件夹中的文件(__init__.py 除外),但包括 __pycache__ 文件夹。

我的应用程序的模型是一个文件夹中的多个文件,其中包含一个带有一些导入的 __init__.py 文件和一个 __all__ 变量(我不知道这是否重要)。

根据提示,我给出第一个迁移命令,它看起来可以工作(迁移 session 、管理、身份验证、注册、内容类型。没有我的应用程序“核心”)。

所以我给出第一个 makemigrations 命令,然后再次给出 migrate 命令。 这次出现错误:

ValueError: invalid literal for int() with base 10: 'basic'

在模型中,有一个默认为“basic”的外键字段。 basic 将是相关类的对象,但实际上它不存在(在创建数据库之前,然后我将填充它)。我认为这很正常。

无论如何,我更改了 default=1 并且它有效(但 1 不会是一个对象,所以这是错误的!)

我的模型:

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

有办法使用“基本”吗?我宁愿不使用 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

最佳答案

在您的付款模型中,您尚未明确指定主键。所以 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可以选择显式引用 Payment 类中的不同字段。

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 ProfileUser(models.Model):
    payment = models.ForeignKey(Payment, blank=True, null=True, 
        default='basic', on_delete=models.PROTECT,
        to_field = 'name' )
    #etc

现在这里的支付字段变成了CharField。请注意,在大多数情况下,使用整数字段作为外键会更有效。

另一种可能性是您将 Payment 中的 name 字段定义为主键。

关于python - 外键默认值的 ValueError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37070557/

相关文章:

python - 确定哪个玩家正在移动

python - django.db.utils.OperationalError : no such column: django_content_type. 名称?

sql-server - 事件源和 SQL Server 多个关系表

python - 导入_socket : "Import Error: DLL load failed"

python - NetworkX 的所有最低共同祖先

python - 如何在 Python 中生成只有 'x' ,'y' 和给定长度 n 的回文列表?

django - django表单提交后触发引导模式

django - 如何最好地将 Django 模型的转换值传递到上下文?

Django 外键多对一关系显示在模板上

python-3.x - 如何在 Django 中进行计算外键对象的查询?