#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`

 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
 custom-parameters-to-formset-forms docs]

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

 In admin I have:

 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:

 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`:

 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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
For more options, visit https://groups.google.com/d/optout.

Reply via email to