python - 为 formset 中的每个表单提供不同的 kwargs

标签 python django forms django-forms

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

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问题,解释如何为多种形式传递初始数据,但它与将其传递给查询集不同。

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

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

Select a valid choice. That choice is not one of the available choices.

我的观点是这样的:

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 .

最佳答案

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

自己解决了:

首先我创建了一个 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

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

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

最后我不得不更新我的表单 init 以弹出列表,这样 super 构造函数就不会提示不需要的 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')

关于python - 为 formset 中的每个表单提供不同的 kwargs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40999075/

相关文章:

python - 数据库设计通讯录

javascript - 如何防止第一次重新渲染 Formik

forms - 表单选择类型字段 symfony 实体中的字段数组类型

python - 二维数组的python总和如何返回列表

python - python\xhhK 中奇怪的十六进制表示

python - 检查文件是否未打开或未被其他进程使用

php - 使用链接提交表单,但 isset 不起作用

python - 如何在 PyCharm 中正确设置 pipenv?

django - 无法运行 django-admin

Django 2.1 如何在迁移中创建用户