2015-04-17 34 views
3

我正面臨OneToOneField的一個非常奇怪的問題。我一直喜歡ValueError:無法分配用戶:我的OneToOneField關係上的問題

class Doctor(models.Model): 
    user = models.OneToOneField(User) 

的問題是一個非常簡單的模型,我在遷移方法RunPython。我寫了一個0002_addusers遷移取決於0001_initial,代碼如下:

class Migration(migrations.Migration): 
    def create_users(apps, schema_editor): 
     u = User.objects.create_superuser('admin', '[email protected]', 'admin') 
     u.save() 

     du = User.objects.create_user(username='doc01', password='doc01') 
     du.save() 

def create_doctors(apps, schema_editor): 
    Doctor = apps.get_model('custom_user', 'Doctor') 
    du = User.objects.get(username='doc01') 

    d = Doctor(user=du) 
    d.save() 

dependencies = [ 
    ('custom_user', '0001_initial') 
] 

operations = [ 
    migrations.RunPython(create_users), 
    migrations.RunPython(create_doctors), 
] 

什麼是很奇怪的,我是,這非常簡單的代碼工作的意見,在外殼的作品,作品無處不在,除了在遷移:)

回溯是如下:

line 23, in create_doctors 
d = Doctor(user=du) 
... 
ValueError: Cannot assign "<User: doc01>": "Doctor.user" must be a "User" instance. 

謝謝你很多關於任何支持!

編輯: 我找到了解決方案。我只好打電話給RunPython

migrations.RunPython(create_users,create_doctor)

Avinash建議,即使沒有移動類之外的功能。

似乎後續函數必須作爲單個RunPython調用的參數被調用。

回答

2

我認爲問題出在您的遷移代碼中。在Migration類外定義你的方法,然後從遷移的RunPython命令中調用它。

請在您的遷移文件中嘗試以下代碼。這將工作。

def create_users(apps, schema_editor): 
    u = User.objects.create_superuser('admin', '[email protected]', 'admin') 
    u.save() 

    du = User.objects.create_user(username='doc01', password='doc01') 
    du.save() 

def create_doctors(apps, schema_editor): 
    Doctor = apps.get_model('custom_user', 'Doctor') 
    du = User.objects.get(username='doc01') 
    # We can't import the Doctor model directly, But we can create it. Try this - 
    Doctor.objects.create(user=du) 

class Migration(migrations.Migration): 

    dependencies = [ 
     ('custom_user', '0001_initial') 
    ] 

    operations = [ 
     migrations.RunPython(create_users, create_doctors), 
    ] 
+0

嗨,謝謝你的回覆,但它不起作用。這個錯誤與我在帖子中的相同。 ValueError:無法分配「」:「Doctor.user」必須是「用戶」實例。 – ennioma

+0

剛剛更新了我的答案。嘗試一下。這應該是解決方案。我們無法直接在遷移中導入模型。 試試吧,讓我知道 –

+0

我已經更新了第一篇文章。謝謝Avinash,問題是我自己對RunPython的調用。現在,如果函數在遷移類中,則新的RunPython也可以工作。 – ennioma

1

運行migrations.RunPython(create_users, create_doctor)的建議答案不能解決您的問題,它只是使其不可見。

RunPython的第二個參數是在回滾期間將被調用的函數,這就是爲什麼它在向上遷移時不會引發任何異常。您從未稱呼功能create_doctors

您的問題是由du不是User實例造成的。當不使用apps.get_model來獲取模型類時,可能會導致遷移。你應該使用下面的代碼來代替:

class Migration(migrations.Migration): 
    def create_users(apps, schema_editor): 
     User = apps.get_model('auth', 'User') # Here you get the user programatically, it is a good practise in migrations 
     u = User.objects.create_superuser('admin', '[email protected]', 'admin') 
     u.save() 

     du = User.objects.create_user(username='doc01', password='doc01') 
     du.save() 

    def create_doctors(apps, schema_editor): 
     Doctor = apps.get_model('custom_user', 'Doctor') 
     User = apps.get_model('auth', 'User') # Here you get the user programatically, it is a good practise in migrations 
     du = User.objects.get(username='doc01') 

     d = Doctor(user=du) 
     d.save() 

    dependencies = [ 
     ('custom_user', '0001_initial') 
    ] 

    operations = [ 
     migrations.RunPython(create_users), 
     migrations.RunPython(create_doctors), 
    ]