#27240: Docs - Passing custom parameters to formset forms in admin
-----------------------------+---------------------------------------------
Reporter: arogachev | Owner: nobody
Type: | Status: new
Uncategorized |
Component: | Version: 1.10
contrib.admin |
Severity: Normal | Keywords: admin, form, formset, parameter
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
-----------------------------+---------------------------------------------
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]
{{{#!python
enterprise = Enterprise()
AttachmentFormSet = generic_inlineformset_factory(Attachment,
form=AttachmentForm, max_num=3, validate_max=True)
if request.method == 'POST':
form = EnterpriseForm(request.POST, request.FILES,
instance=enterprise, user=request.user)
attachment_formset = AttachmentFormSet(request.POST, request.FILES,
instance=enterprise, form_kwargs = {'user': request.user})
# ...
else:
form = EnterpriseForm(instance=enterprise, user=request.user)
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
readonly_fields = ('is_image', 'user', 'created_at')
max_num = 3
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(MyCompareVersionAdmin):
inlines = [AttachmentInline]
def save_related(self, request, form, formsets, change):
AttachmentForm.user = request.user
super(MyCompareVersionAdmin, 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.
--
Ticket URL: <https://code.djangoproject.com/ticket/27240>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.34a9dc5b510c237991c303e5993d2276%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.