'django dynamic forms setting max_length property
I am creating a 'Forms Management' system for my application.
I am creating a forms dynamically using a custom form 'factory' method.
Form data is in a json file.
I can create a forms.CharField and set the label, required, initial and help_text properties.
When I try to set the max_length property I do not get any error message, but the resulting HTML does not contain the max_length attribute.
In static (class) forms defined as
class SearchAccountForm(forms.Form):
provider_code = forms.CharField(
label='Provider:',
max_length=100,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control'}))
The resulting HTML contains the max_length attribute.
<label for="id_provider_code">Provider:</label>
</th><td><input type="text" name="provider_code" class="form-control" maxlength="100" required id="id_provider_code">
So what's up with max_length??
Json file
{
"form1": [
{
"fld_name": "customer_name",
"fld_type": "CharField",
"fld_label": "Cust Name",
"fld_required": "False",
"fld_maxLength": 5,
"initial": "Dr John"
},
{
"fld_name": "customer_number",
"fld_type": "CharField",
"fld_label": "Cust #",
"fld_required": "True",
"fld_maxLength": 15,
"help_text": "Enter account number"
},
{
"fld_name": "customer_type",
"fld_type": "CharField",
"fld_label": "Customer Type",
"fld_required": "False"
}
]
}
and the forms.py factory method
from django import forms
import json
def dynfrm():
f = open('blog/frmJson/frm1.json')
data = json.load(f)
fields = {}
for i in data['form1']: ## form1 = form name in json file
print(i)
## add to fields list
if i['fld_type'] == 'CharField':
fields[i["fld_name"]] = forms.CharField()
if 'fld_label' in i:
fields[i["fld_name"]].label = i["fld_label"]
if 'fld_required' in i:
if i["fld_required"] == 'False':
fields[i["fld_name"]].required = False
else:
fields[i["fld_name"]].required = True
if 'initial' in i: fields[i["fld_name"]].initial = i["initial"]
if 'help_text' in i: fields[i["fld_name"]].help_text = i["help_text"]
## next line not working
if 'fld_maxLength' in i: fields[i["fld_name"]].max_length = i["fld_maxLength"]
fields[i["fld_name"]].widget = forms.TextInput()
return type('DynForm', # form name is irrelevant
(forms.BaseForm,),
{'base_fields': fields})
my view
def vdynfrm(request):
if request.method == 'POST':
form = dynfrm(request.POST)
if form.is_valid():
pass
## all good
else:
form = dynfrm()
##return render(request, "blog/dfrm.html",{'form': form})
return render(request, "blog/searchAccount.html",{'form': form})
and the resulting HTML
<div class="form-group">
<form action="/searchAccount/" method="post">
<table>
<tr>
<th><label for="id_customer_name">Cust Name:</label></th>
<td><input type="text" name="customer_name" value="Dr John" id="id_customer_name">/td>
</tr>
<tr>
<th><label for="id_customer_number">Cust #:</label></th>
<td><input type="text" name="customer_number" required id="id_customer_number"><br>
<span class="helptext">Enter account number</span></td>
</tr>
<tr>
<th><label for="id_customer_type">Customer Type:</label></th>
<td><input type="text" name="customer_type" id="id_customer_type"></td>
</tr>
</table>
<input type="submit" value="Submit">
</form>
</div>
Solution 1:[1]
The max_length
property only works when you send the context
correctly to your template
file.
your forms.py
class SearchAccountForm(forms.Form):
provider_code = forms.CharField(
label='Provider:',
max_length=100,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control'}))
With function
based view:
def home(request):
if request.method == 'POST':
form = SearchAccountForm(request.POST)
if form.is_valid():
provider_c= form.cleaned_data['provider_code']
print('Provider Code :',provider_c)
return HttpResponseRedirect('/thanks/')
else:
form = SearchAccountForm()
return render(request, 'home/index.html', {'form': form})
def thanks(req):
return render(req, 'home/thanks.html')
If you forget to give else
condition for get
request method, so you will not receive django's
inbuild error messages as well as max_length
etc.
With Class based view it can be handled easily:
from django.views.generic.edit import FormView
class Home(FormView):
template_name = 'home/index.html'
form_class = SearchAccountForm
success_url = '/thanks/'
def form_valid(self, form):
print(form)
print('Provider Code : ', form.cleaned_data['provider_code'])
return super().form_valid(form)
def thanks(req):
return render(req, 'home/thanks.html')
From both the examples above max_length
property is working properly because its get
request got handled.
Check your views.py
, it may help.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sunderam Dubey |