I want my forms to be dynamic, some parameters sucj as max_length for IntegerField varies from model to model. By using the information from here, I have written this form:
def my_form(inputname, inputlastname, inputamount):
class MyForm(forms.Form):
name = forms.CharField(max_length=50,required=True,initial=inputname)
lastname = forms.CharField(max_length=50, required=True,initial=inputlastname)
amount= forms.Intege开发者_运维知识库rField(max_value=inputamount, required=True)
return MyForm
It renders well at the template when I call it like this and pass to the template:
form = my_form("David","Bowie",4)()
However I can't figure out how can I validate it, this fails:
if request.method == 'POST': form = MyForm(request.POST) if form.is_valid()
There's no reason to do it this way. You're making things unnecessarily complicated.
Instead of passing the initial values to a factory function which returns a class with those pre-defined, leave out the initial parameters in the form definition, and pass them in during form instantiation:
class MyForm(forms.Form):
name = forms.CharField(max_length=50,required=True)
lastname = forms.CharField(max_length=50, required=True)
...
form = MyForm(request.POST, initial={'firstname':myfirstname, 'surname':mysurname})
Edited after additional question
In order to have a dynamic max_value
for amount, you can override the form's __init__
method and set it there. Then once again you would pass the value in on instantiation.
class MyForm(forms.Form):
name = forms.CharField(max_length=50,required=True)
lastname = forms.CharField(max_length=50, required=True)
amount = forms.IntegerField(required=True)
def __init__(self, *args, **kwargs):
amount_max = kwargs.pop('amount_max', None)
super(MyForm, self).__init__(*args, **kwargs)
if amount_max:
self.fields['amount'].max_value = amount_max
...
form = MyForm(request.POST, amount_max=10,
initial={'firstname':myfirstname, 'surname':mysurname})
精彩评论