【问题标题】:Provide different kwargs for each form in formset为 formset 中的每个表单提供不同的 kwargs
【发布时间】:2017-04-21 07:28:10
【问题描述】:

我正在尝试使用表单集为一组与日期相关的时间范围创建表单:

class Event(models.Model):
   date = models.DateField()

class TimeFrame(models.Model):
   start = models.DateTimeField()
   end = models.DateTimeField()
   event = models.ForeignKey('Event')

我的代码可以让我获得每个事件的时间范围查询集,并添加了一个 kwarg 以将其传递到我的表单中:

class SelectDatesForm(forms.Form):
    timeframes = forms.ModelChoiceField(queryset=HostTimeFrame.objects.none())

    def __init__(self, *args, **kwargs):
       qs = kwargs.pop('timeframes')
       super(SelectDatesForm, self).__init__(*args, **kwargs)
       self.fields['timeframes'].queryset = qs

现在我正在尝试构建一个表单集,让我可以在一页上显示多个事件的时间范围。我已经找到了this 问题,解释了如何为多个表单传递初始数据,但它与将其传递给查询集不同。

还有来自 django 1.9 的 this 新函数,但它不允许我为每个表单获取不同的查询集。

更新: 我从答案中得到了解决方案,但是,每当我运行 formset.is_valid() 时,我都会收到错误:

选择一个有效的选项。该选择不是可用的选项之一 选择。

在我看来,这是我所做的:

timeframes = [HostTimeFrame.objects.all()]
SelectDatesFormset = formset_factory(form=SelectDatesForm, extra=len(timeframes), formset=BaseSelectDatesFormSet)
if request.method == 'POST':
    formset = SelectDatesFormset(request.POST, form_kwargs={'timeframes_list': timeframes})
    if formset.is_valid():
        # do something with the formset.cleaned_data
        print(formset)
        pass
else:
    formset = SelectDatesFormset(form_kwargs={'timeframes_list': timeframes})

我已经尝试了好几个小时来找到这个实际验证的完成位置,但我找不到它为我的生活。

编辑:我用单数形式对此进行了测试,我遇到了同样的问题,我为此 here 创建了一个新问题。

【问题讨论】:

    标签: python django forms django-forms


    【解决方案1】:

    更新: 仅部分解决方案,请参阅问题。

    自己解决了:

    首先我创建了一个 BaseFormSet:

    class BaseSelectDatesFormSet(BaseFormSet):
        def get_form_kwargs(self, index):
            kwargs = super(BaseSelectDatesFormSet, self).get_form_kwargs(index)
            kwargs['timeframes'] = kwargs['timeframes_list'][index]
            return kwargs
    

    然后我可以在视图中传递时间范围列表:

     SelectDatesFormset = formset_factory(form=SelectDatesForm, extra=4, formset=BaseSelectDatesFormSet)
     formset = SelectDatesFormset(form_kwargs={'timeframes_list': timeframes})
    

    最后我不得不更新我的表单 init 以弹出列表,这样超级构造函数就不会抱怨不需要的 kwargs:

    def __init__(self, *args, **kwargs):
        qs = kwargs.pop('timeframes')
        qs_list = kwargs.pop('timeframes_list')
        super(SelectDatesForm, self).__init__(*args, **kwargs)
        self.fields['timeframes'].queryset = qs.order_by('start')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-05
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      相关资源
      最近更新 更多