酥脆的表单字段类型属性被忽略
crispy form field type attribute ignored
我正在尝试在我的 Django 应用程序中使用脆皮表单,但我似乎无法在字段上设置类型属性。
#forms.py
class ReminderForm(ModelForm):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.helper=FormHelper()
self.helper.layout = Layout(
Fieldset('Reminder',
Row(
Div(Field('message'),css_class="col"),
),
Row(
Div(Field('messagetype'),css_class="col-md-6"),
Div(Field('account'),css_class="col-md-6"),
),
Row(
Div(Field('reminddate',type="date"),css_class="col-md-6"),
Div(Field('duedate', type="date"),css_class="col-md-6"),
),
)
)
class Meta:
model=Reminder
exclude=['sentdate','confirmdate','completedate']
我的情态形式
{% load cms_tags crispy_forms_tags %}
<div class="modal fade" id="{{formid}}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{title}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form >
{% crispy form %}
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
为下面的输入呈现 html 显示提醒日期和截止日期样式 with type="text"
<div class="modal-body">
<form>
<fieldset> <legend>Reminder</legend> <div class="form-row "> <div class="col"> <div id="div_id_message" class="form-group"> <label for="id_message" class="">
Message
</label> <div class=""> <textarea name="message" cols="40" rows="10" class="textarea form-control" id="id_message"></textarea> </div> </div> </div>
</div>
<div class="form-row "> <div class="col-md-6"> <div id="div_id_messagetype" class="form-group"> <label for="id_messagetype" class="">
Messagetype
</label> <div class=""> <select name="messagetype" class="select form-control" id="id_messagetype"> <option value="">---------</option> <option value="email">Email</option> <option value="sms">Text Message</option> <option value="internal">Internal Website</option>
</select> </div> </div> </div>
<div class="col-md-6"> <div id="div_id_account" class="form-group"> <label for="id_account" class="">
Account
</label> <div class=""> <select name="account" class="select form-control" id="id_account"> <option value="" selected="">---------</option> <option value="4">jim.pm</option> <option value="2">joe.sp</option> <option value="3">sally.om</option> <option value="1">sparrow</option>
</select> </div> </div> </div>
</div>
<div class="form-row "> <div class="col-md-6"> <div id="div_id_reminddate" class="form-group"> <label for="id_reminddate" class=" requiredField">
Reminddate<span class="asteriskField">*</span> </label> <div class=""> <input type="text" name="reminddate" class="datetimeinput form-control" required="" id="id_reminddate"> </div> </div> </div>
<div class="col-md-6"> <div id="div_id_duedate" class="form-group"> <label for="id_duedate" class=" requiredField">
Duedate<span class="asteriskField">*</span> </label> <div class=""> <input type="text" name="duedate" class="datetimeinput form-control" required="" id="id_duedate"> </div> </div> </div>
</div> </fieldset> </form>
</div>
rendred form
如何正确设置类型属性?其他属性(自定义属性)工作正常。
哦,你想要 type=date,这是一个棘手的问题......你应该制作自己的小部件,但是如果你像我一样懒惰,你可以使用模板过滤器来解决问题:
from django import forms
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.filter
def set_input_type(field, field_type=None):
if field_type:
pass
elif isinstance(field.field.widget, forms.DateInput):
field_type = 'date'
elif isinstance(field.field.widget, forms.TimeInput):
field_type = 'time'
elif isinstance(field.field.widget, forms.SplitDateTimeWidget):
for subfield in field.field.widget.widgets:
if isinstance(subfield, forms.DateInput):
subfield.input_type = 'date'
elif isinstance(subfield, forms.TimeInput):
subfield.input_type = 'time'
elif isinstance(field.field.widget, forms.DateTimeInput):
# field_type = 'datetime-local' # can't work with passing/returning ISO format
# field_type = 'datetime' # is deprecated, doesn't work in many browsers
# use widget=forms.SplitDateTimeWidget() instead
pass
if field_type:
field.field.widget.input_type = field_type
return field
所以你可以像
一样更改模板中的类型
{{ form.dt|set_input_type:'date' }}
但是如果您只使用 {% crispy form %}
,您必须采用第一种(首选)方式并制作您自己的小部件 :)
还有一种方法是使用JS,比如$('#id_reminddate').attr('type', 'date');
顺便说一句,他们可能使用 type=text,因为 type=date 在桌面浏览器中很难看,所以你可以使用一些 JS 库,比如 jqueryui 用于 callendars
@Martin Beran 为我指出了正确的方向。由于我试图继续使用 {% crispy form %} 方法...我发现在 Meta class 中使用小部件覆盖提供了我需要的东西!
class Meta:
model=Reminder
exclude=['sentdate','confirmdate','completedate']
widgets = {
'reminddate': forms.DateInput(attrs={'type':'date'}),
'duedate': forms.DateInput(attrs={'type':'date'})
}
Form with bootstrap date control
我正在尝试在我的 Django 应用程序中使用脆皮表单,但我似乎无法在字段上设置类型属性。
#forms.py
class ReminderForm(ModelForm):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
self.helper=FormHelper()
self.helper.layout = Layout(
Fieldset('Reminder',
Row(
Div(Field('message'),css_class="col"),
),
Row(
Div(Field('messagetype'),css_class="col-md-6"),
Div(Field('account'),css_class="col-md-6"),
),
Row(
Div(Field('reminddate',type="date"),css_class="col-md-6"),
Div(Field('duedate', type="date"),css_class="col-md-6"),
),
)
)
class Meta:
model=Reminder
exclude=['sentdate','confirmdate','completedate']
我的情态形式
{% load cms_tags crispy_forms_tags %}
<div class="modal fade" id="{{formid}}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{title}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form >
{% crispy form %}
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
为下面的输入呈现 html 显示提醒日期和截止日期样式 with type="text"
<div class="modal-body">
<form>
<fieldset> <legend>Reminder</legend> <div class="form-row "> <div class="col"> <div id="div_id_message" class="form-group"> <label for="id_message" class="">
Message
</label> <div class=""> <textarea name="message" cols="40" rows="10" class="textarea form-control" id="id_message"></textarea> </div> </div> </div>
</div>
<div class="form-row "> <div class="col-md-6"> <div id="div_id_messagetype" class="form-group"> <label for="id_messagetype" class="">
Messagetype
</label> <div class=""> <select name="messagetype" class="select form-control" id="id_messagetype"> <option value="">---------</option> <option value="email">Email</option> <option value="sms">Text Message</option> <option value="internal">Internal Website</option>
</select> </div> </div> </div>
<div class="col-md-6"> <div id="div_id_account" class="form-group"> <label for="id_account" class="">
Account
</label> <div class=""> <select name="account" class="select form-control" id="id_account"> <option value="" selected="">---------</option> <option value="4">jim.pm</option> <option value="2">joe.sp</option> <option value="3">sally.om</option> <option value="1">sparrow</option>
</select> </div> </div> </div>
</div>
<div class="form-row "> <div class="col-md-6"> <div id="div_id_reminddate" class="form-group"> <label for="id_reminddate" class=" requiredField">
Reminddate<span class="asteriskField">*</span> </label> <div class=""> <input type="text" name="reminddate" class="datetimeinput form-control" required="" id="id_reminddate"> </div> </div> </div>
<div class="col-md-6"> <div id="div_id_duedate" class="form-group"> <label for="id_duedate" class=" requiredField">
Duedate<span class="asteriskField">*</span> </label> <div class=""> <input type="text" name="duedate" class="datetimeinput form-control" required="" id="id_duedate"> </div> </div> </div>
</div> </fieldset> </form>
</div>
rendred form
如何正确设置类型属性?其他属性(自定义属性)工作正常。
哦,你想要 type=date,这是一个棘手的问题......你应该制作自己的小部件,但是如果你像我一样懒惰,你可以使用模板过滤器来解决问题:
from django import forms
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.filter
def set_input_type(field, field_type=None):
if field_type:
pass
elif isinstance(field.field.widget, forms.DateInput):
field_type = 'date'
elif isinstance(field.field.widget, forms.TimeInput):
field_type = 'time'
elif isinstance(field.field.widget, forms.SplitDateTimeWidget):
for subfield in field.field.widget.widgets:
if isinstance(subfield, forms.DateInput):
subfield.input_type = 'date'
elif isinstance(subfield, forms.TimeInput):
subfield.input_type = 'time'
elif isinstance(field.field.widget, forms.DateTimeInput):
# field_type = 'datetime-local' # can't work with passing/returning ISO format
# field_type = 'datetime' # is deprecated, doesn't work in many browsers
# use widget=forms.SplitDateTimeWidget() instead
pass
if field_type:
field.field.widget.input_type = field_type
return field
所以你可以像
一样更改模板中的类型{{ form.dt|set_input_type:'date' }}
但是如果您只使用 {% crispy form %}
,您必须采用第一种(首选)方式并制作您自己的小部件 :)
还有一种方法是使用JS,比如$('#id_reminddate').attr('type', 'date');
顺便说一句,他们可能使用 type=text,因为 type=date 在桌面浏览器中很难看,所以你可以使用一些 JS 库,比如 jqueryui 用于 callendars
@Martin Beran 为我指出了正确的方向。由于我试图继续使用 {% crispy form %} 方法...我发现在 Meta class 中使用小部件覆盖提供了我需要的东西!
class Meta:
model=Reminder
exclude=['sentdate','confirmdate','completedate']
widgets = {
'reminddate': forms.DateInput(attrs={'type':'date'}),
'duedate': forms.DateInput(attrs={'type':'date'})
}
Form with bootstrap date control