Django - 向内联表单集传递参数

5 投票
1 回答
5520 浏览
提问于 2025-04-17 01:30

我正在使用 inlineformset_factory 来创建一个多对多关系的字段,这个关系是客户(Clients)和会议(Sessions)之间的,另外还有一个中间模型叫做出席(Attendance)。

在我的视图文件中,我有以下内容:

AttendanceFormset = inlineformset_factory(
    Session,
    Attendance,
    formset=BaseAttendanceFormSet,
    exclude=('user'),
    extra=1,
    max_num=10,
    )

session = Session(user=request.user)
formset = AttendanceFormset(request.POST, instance=session)

因为我需要修改其中一个表单字段,所以我在表单集的基础类中添加了以下内容:

class BaseAttendanceFormSet(BaseFormSet):

    def add_fields(self, form, index):
        super(BaseAttendanceFormSet, self).add_fields(form, index)
        form.fields['client'] = forms.ModelChoiceField(
                queryset=Client.objects.filter(user=2))

现在,表单可以正常工作了,但我需要向表单集传递一个值,这样我就可以根据当前用户来过滤显示的客户,而不是仅仅使用id为2的客户。

有没有人能帮忙?

任何建议都非常感谢。

谢谢。

编辑

给所有阅读的人,这就是对我有效的内容:

def get_field_qs(field, **kwargs):
        if field.name == 'client':
            return forms.ModelChoiceField(queryset=Client.objects.filter(user=request.user))
        return field.formfield(**kwargs)

1 个回答

8

你可以考虑使用inlineformset_factory里的formfield_callback参数,而不是直接提供一个formset。这个参数允许你提供一个可调用的函数,这个函数会返回在表单中应该使用的字段。

这个字段回调函数的第一个参数是字段本身,后面可以接一些可选的参数(比如:小部件)。

举个例子(这里用request.user来过滤,如果需要可以换成其他的):

def my_view(request):
    #some setup code here

    def get_field_qs(field, **kwargs):
        formfield = field.formfield(**kwargs)
        if field.name == 'client':
            formfield.queryset = formfield.queryset.filter(user=request.user)
        return formfield

    AttendanceFormset = inlineformset_factory(
        ...
        formfield_callback=get_field_qs
        ...
    )

    formset = AttendanceFormset(request.POST, instance=session)

想要更好地理解这个内容,可以查看Django的FormSet代码中formfield_callback的用法

撰写回答