Django form.save()清除模型对象数据

时间:2011-05-14 16:39:56

标签: django django-models django-forms django-views

我有一个Django模型,其中包含一系列描述工作订单的字段。然后我有一个用ModelForm创建的表单,但只使用了少数模型的字段。这是我的表格:

class Service_Call_Form(ModelForm):
class Meta:
    model = Work_Order
    fields = ('dateWOCreated', 'dateWORequired', 'problemDescription',
    'resolutionDescription', 'notesToCrew', 'numHours', 'numWorkers')

我有创建工作订单 HTML模板,该模板显示所有字段,但“resolutionDescription”。相比之下,有一个工作订单已完成 HTML模板,它只显示 “resolutionDescription”字段(因为,用户需要做的就是解释问题是如何解决的,而不是编辑原始问题是什么)。

现在,我不明白的是,当我点击模板表单中的“保存”按钮完成工作订单时,显示创建工作订单模板的所有字段被清除为空白,问题解决字段仍然存在。此外,我在视图中设置的所有模型字段(因此,用户无法编辑)仍然存在。

为什么会这样?

我的观点:

def create_service_call(request):
if request.method == 'POST':
    form = Service_Call_Form(request.POST)
    if form.is_valid():
        wo = form.save(commit=False)
        if wo.woID == None:
            wo.woID = new_wo_id()
        wo.dateWOCreated = datetime.date.today()
        wo.systemID = System.objects.get(systemID='2')
        wo.woType = 'R'
        wo.isComplete = 'N'
        wo.save()
        return HttpResponseRedirect('/work-orders/')
else:
        form = Service_Call_Form()
return render_to_response("pages/work_orders/create_service_call.html", {'form': form}, context_instance=RequestContext(request))


def complete_service_call(request, scwoID):
if request.method == 'POST':
    woEdit = Work_Order.objects.get(pk=scwoID)
    form = Service_Call_Form(request.POST, instance = woEdit)
    if form.is_valid():
        form.save()
        return HttpResponseRedirect('/work-orders/')
else:
    if scwoID == None:
        #Really, this should never happen (not have a woID in the url)
        return HttpResponseRedirect('/work-orders/', context_instance=RequestContext(request))
    else:
        wo = Work_Order.objects.get(pk=scwoID)
        form = Service_Call_Form(instance=wo)
return render_to_response("pages/work_orders/complete_service_call.html", {'form': form}, context_instance=RequestContext(request))

模特:

class Work_Order(models.Model):
IS_COMPLETE_CHOICES = (
    ('Y', 'Yes'),
    ('N', 'No'),
)

WO_TYPE_CHOICES = (
    ('P', 'Plumb'),
    ('I', 'Install'),
    ('S', 'Show'),
    ('R', 'Service'),
    ('B', 'Blow down'),
    ('U', 'Start up'),
)

woID = models.CharField(max_length = 10, primary_key = True, default = new_wo_id(), verbose_name = 'Work Order ID')
woType = models.CharField(max_length = 2, verbose_name = 'WO Type', default='R', choices = WO_TYPE_CHOICES)
systemID = models.ForeignKey(System, verbose_name = 'System ID')
notesToCrew = models.TextField(blank = True, null = True, verbose_name = 'Notes to Crew')
dateWOCreated = models.DateField(blank = True, null = True, default=datetime.date.today(), verbose_name = 'Date Created')
dateWORequired = models.DateField(blank = True, null = True, verbose_name = 'Date Required')
numDays = models.DecimalField(max_digits = 3, decimal_places = 0, verbose_name = 'Number of Days to Complete', blank = True, null = True)
numHours = models.DecimalField(max_digits = 3, decimal_places = 2, verbose_name = 'Number of Hours to Complete', blank = True, null = True)
isComplete = models.CharField (max_length = 3, default = 'N', verbose_name = 'Is WO Complete?', choices = IS_COMPLETE_CHOICES)
problemDescription = models.TextField(verbose_name = 'Problem Description', blank = True, null = True)
resolutionDescription = models.TextField(verbose_name = 'Resolution Description', blank = True, null = True)
numWorkers = models.DecimalField(max_digits = 3, decimal_places = 0, verbose_name = 'Number of Workers Required', blank = True, null = True)

def __unicode__(self):
    return u'%s - %s' % (self.woID, self.systemID.systemAddress)

class Meta:
    ordering = ['woID']

1 个答案:

答案 0 :(得分:2)

您应该有两种形式,因为您有两种完全不同类型的数据被输入。第一个可以是ModelForm(因为它将一堆字段保存到模型中):

class Service_Call_Form(ModelForm):
    class Meta:
        model = Work_Order
        fields = ('dateWOCreated', 'dateWORequired', 'problemDescription',
                  'notesToCrew', 'numHours', 'numWorkers')

和一个只包含ResolutionDescription的文章,我将其作为常规表单保留(因为它只更新模型中的一个字段)。您可能还希望模型ID是隐藏字段,如果它不存在于URL中,或者使其成为request.POST,否则。

class Resolution_Description_Form(forms.Form):
     resolution_description = forms.TextField(max_length=100)

如果模板来自Service_Call_Form,您的视图保存正确;如果你有resolution_description的内容,你应该只在以下函数中更新该字段:

def complete_work_order(request, scwoID):
    if request.method == 'POST':
        woEdit = Work_Order.objects.get(pk=scwoID)
        form = Resolution_Description_Form(request.POST)
        if form.is_valid():
            woEdit.resolution_description = form.cleaned_data.get('resolution_description')
            woEdit.save()
            return HttpResponseRedirect('/work-orders/')
     ...

编辑:如果你愿意,你也可以只有两个ModelForm。例如,

class Resolution_Description_Form(ModelForm):
    class Meta:
        model = Work_Order
        fields = ('resolutionDescription', )

只需在相应的模板中使用相应的ModelForm,然后保存为您之前保存的内容。