2014-12-19 126 views
0

我有以下的情況,我不知道該怎麼做了更新:​​Django的更新視圖與相關模型

#models.py 
class Task(models.Model): 
    creation_date = models.DateField(
     default=None, 
    ) 
    name = models.CharField(
     max_length=255, 
    ) 
    description = models.TextField(
     max_length=500, 
     blank=True, 
     null=True, 
    ) 

class TaskDetails(models.Model): 
    PEND = 1 
    COMP = 2 
    TASK_STATUS = (
     (PEND, 'pending'), 
     (COMP, 'completed'), 
    ) 
    task = models.OneToOneField(
     Task, 
     primary_key=True, 
     on_delete=models.CASCADE 
    ) 
    solution = models.CharField(
     max_length=255, 
    ) 
    due_date = models.DateField(
     null=True, 
     default=None, 
     blank=True, 
    )  
    status = models.PositiveSmallIntegerField(
     default=1, 
     choices=TASK_STATUS, 
    ) 

現在我的看法

#views.py 
class TaskUpdate(UpdateView): 
    model = Task 
    second_model = TaskDetails 
    form_class = TaskForm 
    second_form_class = TaskDetailsForm 
    pk_url_kwarg = 'task_id' 

    def get_context_data(self, **kwargs): 
     context = super(TaskUpdate, self).get_context_data(**kwargs) 
     if self.request.method == 'POST': 
      details_form = self.second_form_class(self.request.POST, prefix='details') 
     else: 
      details_object = self.second_model.objects.get(pk=self.kwargs.get(self.pk_url_kwarg)) 
      details_form = self.second_form_class(instance=details_object, prefix='details') 

     context['details_form'] = details_form 
     return context 

    def post(self, request, *args, **kwargs): 
     self.object = self.get_object() 
     form = self.form_class(request.POST) 
     details_form = self.second_form_class(request.POST, prefix='details') 
     if form.is_valid() and details_form.is_valid(): 
      return self.form_valid(form, details_form) 
     else: 
      return self.form_invalid(form, details_form) 

    def form_valid(self, form, details_form): 
     form.instance.creation_date = datetime.now().date() 
     self.object = form.save() 
     details_form.instance.task = self.object 
     details_form.save() 
     return HttpResponseRedirect(self.success_url) 

    def form_invalid(self, form, details_form): 
     return self.render_to_response(self.get_context_data(form=form, details_form=details_form)) 

我也有ModelForms:TaskFormTaskDetailsForm。這裏不相關。 2種形式一次顯示並提交。 但不是更新的任務和TaskDetails表中現有的記錄,它會創建兩個表

在一個新的,我認爲我的問題是在form_valid。我應該放什麼? 非常感謝

回答

0

我認爲這應該有效。你不需要form_validform_invalid方法,在這種情況下,

def post(self, request, *args, **kwargs): 
    response = super(TaskUpdate, self).post(request, *args, **kwargs) 
    details_form = self.second_form_class(self.request.POST, prefix='details') 
    if details_form.is_valid(): 
     task = self.get_object() 
     self.second_model.objects.filter(task=task) 
           .update(**details_form.cleaned_data) 
     return response 
    return render(request, self.template_name, { 
     'form': self.get_form(self.get_form_class()), 
     'details_form': details_form, 
    }) 

PS:把related_name=task_detailsOneToOneFieldauto_now_add=True爲任務的創建日期

不過,你爲什麼不包括任務詳細信息並停止使用此OneToOneKey?

+0

here if'details_form.is_valid()''? – 2014-12-19 12:46:19

+0

我做了一些修改來修復一些錯誤但我仍然得到這個錯誤:*'TaskDetails'對象沒有屬性'更新'* – zwan 2014-12-19 13:31:38

+0

是的,因爲你從「過濾器」更改爲「get」。另一種方法是採取''task.task_details' '對象,然後逐個更新它的字段 – 2014-12-19 13:35:49

1

方法形式創建沒有實例。你必須在那裏傳遞你的實例。

def post(self, request, *args, **kwargs): 
    # get current task 
    obj = self.get_object() 
    #initiate the task form with this object as instance 
    form = self.form_class(request.POST, instance=obj) 

    #get realted details object or None. 
    #I can't check if this string works, but it should. 
    details_obj = getattr(object, 'taskdetails', None) 

    #initiate the details_form with this details_object as instance 
    details_form = self.second_form_class(request.POST, prefix='details', 
                 instance=details_obj) 

    if form.is_valid() and details_form.is_valid(): 
     return self.form_valid(form, details_form) 
    else: 
     return self.form_invalid(form, details_form) 

def form_valid(self, form, details_form): 

    #save object 
    obj = form.save(commit=False) 
    obj.creation_date = datetime.now().date() 
    obj.save() 

    #save details_object 
    details_obj = details_form.save(commit=False) 
    details_obj.task = obj 
    details_obj.save() 

    return HttpResponseRedirect(self.success_url) 
+0

你能展示如何在代碼中做到這一點?我其實是新的django – zwan 2014-12-19 12:05:03

+0

工作!謝謝親愛的 – zwan 2014-12-19 13:01:09

+0

是的,這也是如此。但是你沒有使用''UpdateView''的潛力。 – 2014-12-19 13:39:07