2014-03-01 54 views
0

我使用基於類的視圖,但表單有兩個基本模型,而不是一個。因此,「主」形式(僱員,視圖知道)​​具有另一個形式對象。Django forms.ModelForm.save()的行爲:爲什麼models.save_instance不能通過父級工作?

Shift的模型有一個pkey,引用Employees的一個元素。

我想知道,爲什麼這是行不通的:

class ShiftSubForm(forms.ModelForm): 

    def __init__(self, *args, **kwargs): 
    super(ShiftSubForm, self).__init__(*args, **kwargs) 
    ... some adjustment of widgets, deleting and adding form fields 

    class Meta: 
     model=Shift 


class EmployeeForm(forms.ModelForm): 
    second_form = None 

    def __init___(self, *args, **kwargs): 
    kwargs.update({'instance': kwargs['shift']}) 
    del kwargs['shift'] 
    self.second_form = ShiftSubForm(*args, **kwargs) 

    def save(self): 
     employee = super(ShiftSubForm, self).save() 
     self.second_form.cleaned_data.update({'employee': employee}) 
     self.second_form.save() 

    class Meta: 
     model = Employee 

我期望的()保存ShiftSubForm的父母打電話models.save_instance(..)和保存數據。但它失敗了,因爲employee_id爲空,所以出現完整性錯誤。所以員工對象沒有進入保存狀態。

但是,如果我直接調用它,它的工作原理:

class ShiftSubForm(forms.ModelForm): 
    ... as above ... 

    def save(self): 
     return models.save_instance(self, self.instance, self._meta.fields, 
      fail_message, True, exclude=self._meta.exclude) 

我在想什麼?

編輯:不能回答自己,所以這裏...

認爲,這可能是最好的辦法嗎?

class ShiftSubForm(forms.ModelForm): 
    ... as above ... 

    def createInstanceWith(self,employee): 
     self.save(commit=False)    # prepares self.instance 
     self.instance.employee = employee 

class EmployeeForm(forms.ModelForm): 
    ... 

    def save(self): 
     employee = super(ShiftSubForm, self).save() 
     self.second_form.full_clean() # populates its self.cleaned_data 
     self.second_form.createInstanceWith(employee) 
     self.second_form.save() 

PS:忽略拼寫錯誤 - 這不是真正的代碼。但它擁有一切,與形式摸索

+0

(上一則留言刪除,因爲沒有仔細閱讀不夠) – lanzz

+0

通常情況下,我會叫'is_valid()'爲兩種形式,所以就沒有必要調用'full_clean()'。我不確定我是否會選擇將其中一個形式作爲另一個屬性的方法,但如果它對您有用,並且您瞭解它,那麼它看起來沒問題。 – Alasdair

回答

1

不要更新cleaned_data。請致電save()commit=False,設置員工,然後將其保存到數據庫。

class EmployeeForm(forms.ModelForm): 
    second_form = None 

    def save(self): 
     employee = super(ShiftSubForm, self).save() 
     shift = self.second_form.save(commit=False) 
     shift.employee = employee 
     shift.save() 
     return employee 

    class Meta: 
     model = Employee 
+0

感謝您的提示,這讓我走上了正軌(至少更好)。 –

+0

我做了:shift.employee.instance = employee –

+0

這聽起來不太正確 - 'shift.employee'沒有實例屬性。像上面的問題一樣設置'self.instance.employee',看起來更好。 – Alasdair

相關問題