【问题标题】:Django - Passing parameters to inline formsetDjango - 将参数传递给内联表单集
【发布时间】:2011-11-10 18:29:59
【问题描述】:

我正在使用 inlineformset_factory 为客户和会话之间的多对多关系创建字段,并使用中介出勤模型。

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

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)

【问题讨论】:

    标签: python django formset


    【解决方案1】:

    使用 inlineformset_factory 的 formfield_callback 参数而不是提供一个 formset 怎么样?提供一个可调用对象,该可调用对象依次返回应在表单中使用的字段。

    表单字段回调将字段作为第一个参数,**kwargs 用于可选参数(例如:小部件)。

    例如(使用 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)
    

    为了更好的理解,请看formfield_callback in Django's FormSet code的用法。

    【讨论】:

    • 您好,感谢您的回复。我尝试添加您在上面放置的内容(尽管我必须返回 field.formfield(**kwargs) 而不仅仅是字段),但它现在返回所有客户端对象。我已阅读 django 工具栏中的查询,但未应用过滤器。我尝试从 if 语句中输出到控制台,所以我知道它正在被击中。知道为什么它可能会忽略它吗?再次感谢。
    • 您能否在第二次尝试时更新您的问题?猜猜你也可以返回 forms.ModelChoiceField(queryset=Client.objects.filter(user=request.user)) 如果字段名为 client
    • 上面的固定示例,在 cmets 中使用更通用的 @mkriheli 解决方案实现
    • 是的,很好的解决方案。甚至可以通过覆盖 get_form() 和 get_form_kwargs() 来在 CBFormView 中使用它
    猜你喜欢
    • 2015-08-27
    • 2020-11-05
    • 2020-04-13
    • 1970-01-01
    • 2013-01-17
    • 2013-11-20
    • 2015-07-10
    • 2020-03-21
    • 1970-01-01
    相关资源
    最近更新 更多