将 init 方法放在 InLineFormSet 上

Putting an init method on an InLineFormSet

我使用了 InLineFormSet 来显示与特定时间表相关的所有记录。用户可以在页面上添加许多新表单,我使用 ajax 和 html 在底部附加一个空的 existing_form 和新 ID。然而,保存这是一个问题....因为新添加的表单还没有分配 timesheet_id,它们不会保存为 existing_forms 的一部分。

我正在尝试将一个 init 方法放在一起,以便在创建表单时分配它,希望能解决这个问题。 (?)

1) 我必须先保存记录才能成为 existing_form 集的一部分吗?

2) 我已经从 TimeForm 中排除了 timesheet_id....这意味着我假设 form.timesheet_id = var 将不起作用...我将不得不使用 obj.timesheet_id...但是我可以在表单的初始部分执行此操作吗?很困惑。

3) 新添加的表单使用新的表单集是否更容易modelformset_factory.....

查看:

class CustomInlineFormSet(BaseInlineFormSet):
    def clean(self):
        super(CustomInlineFormSet, self).clean()
        timesheet = TimeSheet.objects.get(pk=timesheet_id)
        for form in self.forms:
            form.empty_permitted = True
    def __init__(self, request, *args, **kwargs):
        super(CustomInlineFormSet, self).__init__(*args,**kwargs)
        # the following won't work because it's excluded from the form?
        # self.fields['timesheet_id'] = forms....... oh no
        timesheet_fromview = request.session.get('timesheet')
        print timesheet_fromview
        for form in self.forms:
            obj = form.save(commit=False)
            obj.timesheet_id = timesheet_fromview

        try:
            del request.session['timesheet']
            print "session deleted"
        except KeyError:
            pass
            print "Key error raised"



def timesheet(request, timesheet_id):
    timesheet = TimeSheet.objects.get(pk=timesheet_id)

    TimeInlineFormSet = inlineformset_factory(TimeSheet, Time, exclude=('timesheet_id',), extra=0, formset=CustomInlineFormSet)

    if request.method == 'POST':
        # instance is not yet timesheet.... no foreign key in new fields so doesn't do anything
        existing_formset = TimeInlineFormSet(request.POST, request.FILES, instance=timesheet)

        for thetime in existing_formset.forms:
            # obj = thetime.save(commit=False)
            # obj.timesheet_id = timesheet
            # obj.save()
            # print obj
            if thetime.is_valid():
                print "existing time is valid"
                thetime.save()
            else:
                "existing time is not valid"

        context = {
            "timesheet": timesheet,
            "existing_formset": existing_formset,
        }    
        return render(request, 'tande/timesheet.html', context)
    else:
        print "method is not post"
        existing_formset = TimeInlineFormSet(instance=timesheet)
        new_timeformset = NewTimeFormSet()
        request.session['timesheet'] = timesheet
        context = {
            "timesheet": timesheet,
            "existing_formset": existing_formset,
        }    
        return render(request, 'tande/timesheet.html', context)

我通过在我的视图中使用两个单独的表单集来解决这个问题,一个内联用于现有记录,一个模型表单集用于新增内容。然后我用一个字段分别保存这两个字段,当记录是新添加时该字段为 True,当它在现有表单集中时为 False:

class Time(models.Model):
    project_id = models.ForeignKey(Project, null=True)
    date_worked = models.DateField(null=True, blank=True)
    hours = models.CharField(max_length=1)
    description = models.CharField(max_length=150)
    timesheet_id = models.ForeignKey(TimeSheet, null=True)
    add_row = models.CharField(max_length=10, default=True, editable=False)
    def __unicode__ (self):
        return self.description

视图分别保存两个表单集:

def timesheet(request, timesheet_id):
    timesheet = TimeSheet.objects.get(pk=timesheet_id)

    TimeInlineFormSet = inlineformset_factory(TimeSheet, Time, exclude=('timesheet_id',), extra=0, formset=CustomInlineFormSet)
    NewTimeFormSet = modelformset_factory(Time, form=TimeForm, formset=RequiredFormSet)

    if request.method == 'POST':
        existing_formset = TimeInlineFormSet(request.POST, request.FILES, instance=timesheet)
        newtime_formset = NewTimeFormSet(request.POST, request.FILES)

        for orange in newtime_formset:
            obj = orange.save(commit=False)
            if obj.add_row == "True":
                obj.timesheet_id = timesheet
                obj.add_row = "False"
                obj.save()

        for thetime in existing_formset.forms:
            if thetime.is_valid():
                thetime.save()

        existing_formset = TimeInlineFormSet(instance=timesheet)
        newtime_formset = NewTimeFormSet()
        context = {
            "timesheet": timesheet,
            "existing_formset": existing_formset,
            "newtime_formset": newtime_formset,
        }    
        return render(request, 'tande/timesheet.html', context)