Django向窗体传递自定义窗体参数

2024-03-28 22:49:31 发布

您现在位置:Python中文网/ 问答频道 /正文

This was fixed in Django 1.9 with form_kwargs.

我有一张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()

现在我如何通过这种方式将affiliate=request.affiliate传递给各个表单?


Tags: djangoselfform表单objectsrequestcustomforms
3条回答

我将在一个函数中动态构建表单类,以便它可以通过闭包访问分支:

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

另外,您不必重写选项字段中的queryset。缺点是子类化有点古怪。(任何子类都必须以类似的方式创建。)

编辑:

作为对注释的响应,可以在任何使用类名的位置调用此函数:

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)
    ...

我会用functools.partialfunctools.wraps

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(即,使其难以子类化)。

公文方式

Django 2.0版:

ArticleFormSet = formset_factory(MyArticleForm)
formset = ArticleFormSet(form_kwargs={'user': request.user})

https://docs.djangoproject.com/en/2.0/topics/forms/formsets/#passing-custom-parameters-to-formset-forms

相关问题 更多 >