Django将自定义表单参数传递给Formset

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (57)

我有一个Django表单,如下所示:

class ServiceForm(forms.Form):
    option = forms.ModelChoiceField(queryset=ServiceOption.objects.none())
    rate = forms.DecimalField(widget=custom_widgets.SmallField())
    units = forms.IntegerField(min_value=1, widget=custom_widgets.SmallField())

    def __init__(self, *args, **kwargs):
        affiliate = kwargs.pop('affiliate')
        super(ServiceForm, self).__init__(*args, **kwargs)
        self.fields["option"].queryset = ServiceOption.objects.filter(affiliate=affiliate)

我用这样的方式来称呼这个表格:

form = ServiceForm(affiliate=request.affiliate)

何地request.affiliate是登录用户。这按预期工作。

我的问题是,我现在想把这个单一的表单转换成一个表单集。我不明白的是,在创建表单集时,我如何将附属信息传递给各个表单。根据这些文档,我需要这样做:

ServiceFormSet = forms.formsets.formset_factory(ServiceForm, extra=3)

然后我需要像这样创建它:

formset = ServiceFormSet()

现在,我如何以这种方式将UNIATE=request.UNITATE传递给各个表单?

提问于
用户回答回答于

我会用函数部分和函数包装:

from functools import partial, wraps
from django.forms.formsets import formset_factory

ServiceFormSet = formset_factory(wraps(ServiceForm)(partial(ServiceForm, affiliate=request.affiliate)), extra=3)

我认为这是最干净的方法,并且不会以任何方式影响ServiceForm(即使子类变得很困难)。

用户回答回答于

我将在函数中动态构建表单类,以便它可以通过闭包访问附属机构:

def make_service_form(affiliate):
    class ServiceForm(forms.Form):
        option = forms.ModelChoiceField(
                queryset=ServiceOption.objects.filter(affiliate=affiliate))
        rate = forms.DecimalField(widget=custom_widgets.SmallField())
        units = forms.IntegerField(min_value=1, 
                widget=custom_widgets.SmallField())
    return ServiceForm

作为奖励,不必重写选项字段中的查询集。缺点是子类有点古怪。(任何子类都必须以类似的方式生成。)

为了响应注释,可以调用这个函数,它涉及你将使用类名的任何位置:

def view(request):
    affiliate = get_object_or_404(id=request.GET.get('id'))
    formset_cls = formset_factory(make_service_form(affiliate))
    formset = formset_cls(request.POST)
    ...

扫码关注云+社区