﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
27240	Passing custom parameters to formset forms in admin	Alexey Rogachev	nobody	"I have `Enterprise` model and related model `Attachment`. Attachments are managed using formsets in both frontend and backend.

I use custom form to handle attachments, and it uses additional `user` kwarg:

{{{#!python
def __init__(self, *args, **kwargs):
    self.user = kwargs.pop('user', None)
    super(AttachmentForm, self).__init__(*args, **kwargs)
}}}

I need to fill this parameter with `request.user` value. In frontend I use the method recommended in [https://docs.djangoproject.com/en/1.9/topics/forms/formsets/#passing-custom-parameters-to-formset-forms docs] (code omitted for brevity).

{{{#!python
enterprise = Enterprise()
AttachmentFormSet = generic_inlineformset_factory(Attachment, form=AttachmentForm, max_num=3, validate_max=True)
if request.method == 'POST':
    attachment_formset = AttachmentFormSet(request.POST, request.FILES, instance=enterprise, form_kwargs = {'user': request.user})
else:
    attachment_formset = AttachmentFormSet(instance=enterprise, form_kwargs = {'user': request.user})
}}}

But docs do not cover how achieve the same thing in backend using Django Admin.

In admin I have:

{{{#!python
class AttachmentInline(GenericTabularInline):
    model = Attachment
    form = AttachmentForm

class EnterpriseAdmin(MyCompareVersionAdmin):
    inlines = [AttachmentInline]
}}}

It's unclear where and how we need to grab and pass `request.user` parameter to `AttachmentForm`. After some trial and error, I ended up with this workaround:

{{{#!python
class EnterpriseAdmin(admin.ModelAdmin):
    inlines = [AttachmentInline]

    def save_related(self, request, form, formsets, change):
        AttachmentForm.user = request.user
        super(EnterpriseAdmin, self).save_related(request, form, formsets, change)
}}}

Related modifications in `AttachmentForm`:

{{{#!python
user = None

def __init__(self, *args, **kwargs):
    user = kwargs.pop('user', None)
    if user:
        self.user = user
        super(AttachmentForm, self).__init__(*args, **kwargs)
}}}

So I turned `user` to class attribute and set it from kwargs only if it's passed and it's not `None`.

It works, but I don't like this approach and It looks like a hack for me.

I think the solution on how to properly do it should be added to the docs in the same section along with frontend solution.

I'm not sure If I can't find the proper way to do that or it's really not implemented for admin."	Uncategorized	new	Documentation	master	Normal		admin, form, formset, parameter		Unreviewed	0	0	0	0	0	0
