2016-05-06 77 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