2016-05-06 37 views
2

我删除了我的db.sqlite3以及我的迁移文件夹上的文件,但__init__.py除外,但包括__pycache__文件夹。关于foreignkey默认值的ValueError

我的应用程序的模型是一个文件夹中的多个文件与__init__.py文件与一些导入和__all__变量(我不知道这件事情)。

从提示符我给第一个迁移命令,它看起来工作(迁移会话,管理,身份验证,注册,contenttypes。有没有我的应用程序'核心')。

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

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

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

反正我在默认= 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

在您的Payment模型中,您没有明确指定主键。所以Django会为你创建一个。它将是一个整数自动增量字段。

Class Payment(models.Model): 
    name = models.CharField(max_length=32) 

现在,当你定义PaymentProfileUser外键,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字段,因为它是主键。

+0

好吧,谢谢你,它的工作原理,但'to_field ='name''与' – fabio

+0

哎呀是监督。将更正。 – e4c5

+0

请原谅我的英语,我的评论可能看起来粗鲁,但我正在寻找确认:) – fabio

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,你确定它会在数据库中吗?解决这个问题的方法之一是使用固定装置填充付款表。

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

+0

它将在数据库中,如果不是,我必须决定使用哪个默认值并编辑该字段。如果你想看看这个相关的问题[链接](http://stackoverflow.com/questions/37076858/prepopulate-database-with-fixtures-or-with-script) – fabio