コメントをありがとう@YujiTomitaそしてここに私の解決策があります:
基本的な考え方は、入力が隠されたフォームセットを生成することです。そのうちの1つは、css/javascriptを呼び出します。
そして、javascriptが値を入力します。
ウィジェット
class OpeningHoursWidget(forms.HiddenInput):
class Media:
js = (
'https://ajax.googleapis.com/[...]jquery-ui.min.js',
'js/business_hours.js',
)
css = {'all': (
'https://ajax.googleapis.com/[...]jquery-ui.custom.css',
'css/business_hours.css',
)}
形
class UserOpeningHoursForm(forms.ModelForm):
class Meta:
model = OpeningHours
fields = ('weekday', 'from_hour', 'to_hour')
widgets = {
'weekday': forms.HiddenInput(attrs={'class': 'hours-weekday'}),
'from_hour': OpeningHoursWidget(attrs={'class': 'hours-start'}),
'to_hour': forms.HiddenInput(attrs={'class': 'hours-end'}),
}
見る
UserOpeningHoursFormSet = formset_factory(UserOpeningHoursForm, extra=0)
obj['formset'] = UserOpeningHoursFormSet(initial=hours)
レンプレート
<div id="slider-block-hidden">
<div class="slider-end"></div>
<div class="slider"></div>
<div class="slider-start"></div>
<div class="slider-day"></div>
</div>
{{ formset.media }}
{% for hours in formset %}
<div class="slider-block">
{{ hours }}
</div>
{% endfor %}
javascript(jqueryを使用)
$(function() {
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
$('.slider-block').each(function () {
start = $(this).find('.hours-start').val();
end = $(this).find('.hours-end').val();
day_id = $(this).find('.hours-weekday').val();
hidden_slider = $('#slider-block-hidden').clone();
$(this).append(hidden_slider.find('.slider-end').text(end));
$(this).append((slider = hidden_slider.find('.slider')));
$(this).append(hidden_slider.find('.slider-start').text(start));
$(this).append(hidden_slider.find('.slider-day').text(days[day_id]));
slider.slider({
orientation: "vertical",
range: true,
min: 0,
max: 1440,
step: 15,
values: [ ttm(start), ttm(end) ],
slide: function( event, ui ) {
$(this).siblings('.slider-start').text(mtt(ui.values[0]));
$(this).siblings('.slider-end').text(mtt(ui.values[1]));
}
});
});
});
ttm()
とmtt()
は分時間変換/フォーマットのための関数です
css
#slider-block-hidden {
display: none;
}
.slider-block {
text-align: center;
display: inline-block;
margin: 10px;
}
.slider {
margin: 10px;
height: 150px;
}
たぶん、多くのjavascriptを回避するために、ウィジェットのレンダリングをサブクラス化する方法があるでしょう。