Django dynamic forms setting max_length property
Я создаю систему 'Forms Management' для своего приложения.
Я создаю форму динамически, используя метод 'фабрики' пользовательской формы.
Данные формы находятся в json-файле.
Я могу создать поле forms.CharField и установить свойства label, required, initial и help_text.
При попытке установить свойство max_length я не получаю никакого сообщения об ошибке, но результирующий HTML не содержит атрибута max_length.
В статических формах, определяемых как
class SearchAccountForm(forms.Form):
provider_code = forms.CharField(
label='Provider:',
max_length=100,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control'}))
Результирующий HTML содержит атрибут max_length.
<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">
Так что же с max_length???
Json файл
{
"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"
}
]
}
и фабричный метод forms.py
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})
и результирующий 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>
Свойство max_length работает только тогда, когда вы правильно отправляете context в ваш template файл.
ваш forms.py
class SearchAccountForm(forms.Form):
provider_code = forms.CharField(
label='Provider:',
max_length=100,
required=True,
widget=forms.TextInput(attrs={'class': 'form-control'}))
С function основанным представлением:
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')
Если вы забыли указать else условие для get метода запроса, вы не получите django's сообщения об ошибке при сборке, а также max_length и т.д.
С представлением на основе классов это можно сделать легко:
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')
В обоих примерах выше max_length свойство работает правильно, потому что его get запрос был обработан.
Проверьте свой views.py, это может помочь.