foreignkey默认值

时间:2016-05-06 10:52:31

标签: python django foreign-keys default-value

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

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

在提示符下,我提供了第一个迁移命令,它看起来有效(迁移会话,管理员,身份验证,注册,内容类型。没有我的应用'核心')。

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

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

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

无论如何我改变了默认= 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

有一种方法可以使用'基本'吗?我更喜欢不使用id = 1,因为我不确定知道基本会有的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

2 个答案:

答案 0 :(得分:2)

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选项明确引用Payment类中的其他字段。

  

ForeignKey.to_field¶关联对象上的字段   是的。默认情况下,Django使用相关对象的主键。

因此你的班级将成为

Class ProfileUser(models.Model):
    payment = models.ForeignKey(Payment, blank=True, null=True, 
        default='basic', on_delete=models.PROTECT,
        to_field = 'name' )
    #etc

现在,此处的付款字段成为CharField。请注意,在大多数情况下使用整数字段作为外键会更有效。

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

答案 1 :(得分:2)

创建一个函数来返回id(将它放在ProfileUser defenition之前)。

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)

虽然如果你不知道id'basic'会有什么,你确定它会在数据库中吗?解决这个问题的一种方法是使用灯具填充付款表。

https://docs.djangoproject.com/en/1.9/howto/initial-data/

相关问题