在表单启动时设置表单值

Setting the form value when the form is initiated

我正在尝试在启动表单时设置字段值。

当我们进入视图时检索此字段的值 - 视图是时间表。然后,对于视图中设置的每个时间,我想将其关联回时间表。

@login_required
@requires_csrf_token
def timesheet(request, timesheet_id):
    timesheet = TimeSheet.objects.get(pk=timesheet_id)
    NewTimeFormSet = modelformset_factory(Time, form=TimeForm, formset=RequiredFormSet)
    if request.method == 'POST':
        newtime_formset = NewTimeFormSet(request.POST, request.FILES)
        for form in newtime_formset:
            if form.is_valid():
                form.save()  

    #then render template etc

因此,为了确保表单有效,我想在表单启动时设置此字段。当我尝试在视图中 POST 之后设置此字段时,我无法设置要设置的字段或要验证的表单。

当模型实例在进入视图时启动时,我的代码得到 timesheet_id

def __init__(self, *args, **kwargs):
        # this allows it to get the timesheet_id
        print "initiating a timesheet"
        super(TimeSheet, self).__init__(*args, **kwargs)

然后生成表格,我运行表格init。这就是我尝试过的

class TimeForm(forms.ModelForm):

    class Meta:
        model = Time
        fields = ['project_id', 'date_worked', 'hours', 'description', 'timesheet_id',]

            # some labels and widgets, the timesheet_id has a hidden input

    def __init__(self, *args, **kwargs):
        print "initiating form"
        super(TimeForm, self).__init__(*args, **kwargs)
        timesheet = TimeSheet.objects.get(id=timesheet_id)
        self.fields['timesheet_id'] = timesheet

这会引发错误

NameError: global name 'timesheet_id' is not defined

我不知道该怎么做...

我也尝试在表单 clean() 方法中设置字段,但它填充(通过打印显示)然后仍然没有验证并且我引发了表单集错误 'This field is required'.

求助!

您实际上并未在表单初始化方法中接受 timesheet_id 参数,因此未定义该值,因此出现错误。

然而,这是错误的做法。将值传递给表单,将其作为隐藏字段输出,然后在您一直拥有它的情况下取回它是没有意义的。这样做的方法是 从表单字段中排除 值,并在保存时设置它。

class TimeForm(forms.ModelForm):

    class Meta:
        model = Time
        fields = ['project_id', 'date_worked', 'hours', 'description',]

...

if request.method == 'POST':
    newtime_formset = NewTimeFormSet(request.POST, request.FILES)
    if newtime_formset.is_valid():
        for form in newtime_formset:
            new_time = form.save(commit=False)
            new_time.timesheet_id = 1  #  or whatever
            new_time.save()

请再次注意,在遍历保存之前,您应该检查整个表单集的有效性;否则你可能会在遇到无效表单之前保存其中的一些。