使用 Django Crispy Forms 呈现单独的 MultiWidget 字段 [英] Rendering separate MultiWidget fields using Django Crispy Forms
问题描述
我的具体情况是我需要在一行中呈现此字段(使用 Bootstrap 3):
比如:
<label>数量:</label><div class="row"><input name="amount_0" type="number" class="col-xs-8"><select name="amount_1" class="col-xs-4">...</select>
使用:https://github.com/jakewins/django-money
小工具:https://github.com/jakewins/django-money/blob/master/djmoney/forms/widgets.py
型号:
from djmoney.models.fields import MoneyField类 MyModel(models.Model):...金额 = MoneyField(...)...
表格:
class MyForm(forms.ModelForm):...@财产定义助手(自我):帮手 = FormHelper()helper.form_tag = Falsehelper.layout = Layout()helper.layout.fields = [...'数量',...]返回帮手...
django-crispy-forms 不处理字段小部件的渲染,django 处理这个问题.django.forms.MultiWidget
也是一样.
django-crispy-forms 不会分别呈现 MultiWidget 中的每个字段.
参见:django.forms.MultiWidget.format_output(rendered_widgets)
这是如何将 MultiWidget 渲染到 twitter-bootstrap-3 列在 Django 1.10 中-:
from djmoney.forms.widgets import MoneyWidget类 CustomMoneyWidget(MoneyWidget):def format_output(自我,render_widgets):return ('<div class="row">''<div class="col-xs-6 col-sm-10">%s</div>''<div class="col-xs-6 col-sm-2">%s</div>''</div>') % 元组(rendered_widgets)类 BookingForm(forms.ModelForm):...def __init__(self, *args, **kwargs):super(BookingForm, self).__init__(*args, **kwargs)金额,货币 = self.fields['amount'].fieldsself.fields['amount'].widget = CustomMoneyWidget(amount_widget=amount.widget,currency_widget=currency.widget)...
对于 Django 1.11+:
由于 change
,需要使用新模板 api
.相反,您的自定义货币小部件应如下所示:
class CustomMoneyWidget(MoneyWidget):template_name = 'widgets/money.html'
使用模板 money.html
<div class="col-xs-6 col-sm-10">{% with widget=widget.subwidgets.0 %}{% 包含 widget.template_name %}{% 以 %} 结尾<div class="col-xs-6 col-sm-2">{% with widget=widget.subwidgets.1 %}{% 包含 widget.template_name %}{% 以 %} 结尾
My specific case is that I need this field rendered in one line (using Bootstrap 3):
So something like:
<div class="form-group">
<label>Amount:</label>
<div class="row">
<input name="amount_0" type="number" class="col-xs-8">
<select name="amount_1" class="col-xs-4">...</select>
</div>
</div>
Using: https://github.com/jakewins/django-money
Widget: https://github.com/jakewins/django-money/blob/master/djmoney/forms/widgets.py
Model:
from djmoney.models.fields import MoneyField
class MyModel(models.Model):
...
amount = MoneyField(...)
...
Form:
class MyForm(forms.ModelForm):
...
@property
def helper(self):
helper = FormHelper()
helper.form_tag = False
helper.layout = Layout()
helper.layout.fields = [
...
'amount',
...
]
return helper
...
django-crispy-forms does not handle the rendering of the field widget, django handles that. It is the same with django.forms.MultiWidget
.
django-crispy-forms does not render each field from the MultiWidget separately.
See: django.forms.MultiWidget.format_output(rendered_widgets)
This is how to render a MultiWidget to twitter-bootstrap-3 columns In Django 1.10-:
from djmoney.forms.widgets import MoneyWidget
class CustomMoneyWidget(MoneyWidget):
def format_output(self, rendered_widgets):
return ('<div class="row">'
'<div class="col-xs-6 col-sm-10">%s</div>'
'<div class="col-xs-6 col-sm-2">%s</div>'
'</div>') % tuple(rendered_widgets)
class BookingForm(forms.ModelForm):
...
def __init__(self, *args, **kwargs):
super(BookingForm, self).__init__(*args, **kwargs)
amount, currency = self.fields['amount'].fields
self.fields['amount'].widget = CustomMoneyWidget(
amount_widget=amount.widget, currency_widget=currency.widget)
...
For Django 1.11+:
Due to a change
, you need to use the new template api
. Instead, your custom money widget should look like:
class CustomMoneyWidget(MoneyWidget):
template_name = 'widgets/money.html'
With template money.html
<div class="row">
<div class="col-xs-6 col-sm-10">
{% with widget=widget.subwidgets.0 %}
{% include widget.template_name %}
{% endwith %}
</div>
<div class="col-xs-6 col-sm-2">
{% with widget=widget.subwidgets.1 %}
{% include widget.template_name %}
{% endwith %}
</div>
</div>
这篇关于使用 Django Crispy Forms 呈现单独的 MultiWidget 字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!