0

I have an inline formset in Django. And I wonder how can I set some max_value for a form that is in this formset based on the instance parameters. The problem is that when we create a formset by using inlineformset_factory we pass there not an instance of the form, but the class, so I do not know how to pass the parameters there.

when the form is initiated, there is already an instance object available in kwargs that are passed there. But for some strange reasons, when I try to set max_value nothing happens. Right now I've found quite an ugly solution to set the widget max attribute. This one works but I wonder if there is a correct way of doing it.

from .models import SendReceive, Player

from django.forms import inlineformset_factory, BaseFormSet, BaseInlineFormSet


class SRForm(forms.ModelForm):
        amount_sent = forms.IntegerField(label='How much to sent?',
                                         required=True,
                                         widget=forms.NumberInput(attrs={'min': 0, 'max': 20})
                                         )

        def __init__(self, *args, **kwargs):
            super(SRForm, self).__init__(*args, **kwargs)
            curmax = kwargs['instance'].sender.participant.vars['herd_size']
            self.fields['amount_sent'].widget.attrs['max'] = int(curmax)

        class Meta:
            model = SendReceive
            fields = ['amount_sent']


SRFormSet = inlineformset_factory(Player, SendReceive,
                                      fk_name='sender',
                                      can_delete=False,
                                      extra=0,
                                      form=SRForm,)
formset = SRFormSet(self.request.POST, instance=self.player)
Philipp Chapkovski
  • 1,949
  • 3
  • 22
  • 43

1 Answers1

1

You could use functools to create a curried version of your Form class:

from functools import partial, wraps


# create a curried form class
form_with_params = wraps(SRForm)(partial(SRForm, your_param='your_value'))

# use it instead of the original form class
SRFormSet = inlineformset_factory(
                             Player,
                             SendReceive,
                             # ...
                             form=form_with_params,
                           )
olieidel
  • 1,505
  • 10
  • 10
  • Thank you! I just solved a bit otherwise, but your solution looks like more universal. Here is how I did it: https://gist.github.com/chapkovski/b6fd6134124d88d671ed7b3b1baa4b81 So instead of re-writing `max_value` it was enough to re-write an entire field in init. – Philipp Chapkovski Sep 18 '17 at 09:42