Django - 时间范围小部件

Posted

技术标签:

【中文标题】Django - 时间范围小部件【英文标题】:Django - Time range widget 【发布时间】:2012-08-26 09:49:10 【问题描述】:

我想使用jQueryUI Slider 作为允许配置营业时间的小部件。

所以我做了这个模型:

WEEKDAYS = [
  (1, _("Monday")),
  (2, _("Tuesday")),
  (3, _("Wednesday")),
  (4, _("Thursday")),
  (5, _("Friday")),
  (6, _("Saturday")),
  (7, _("Sunday")),
]

class OpeningHours(models.Model)
    comp = models.ForeignKey('Company')
    weekday = models.IntegerField(choices=WEEKDAYS, unique=True)
    from_hour = models.TimeField()
    to_hour = models.TimeField()

class Company(models.Model):
    name = models.CharField(max_length=100)
    logo = models.FileField(upload_to='company_logos')

我知道执行控制器的标记,例如:

<div class="slider-block">
    <div class="slider-end">18:00</div>
    <div class="slider"></div>
    <div class="slider-start">08:00</div>
    <div class="slider-day">Tue</div>
</div>

这给出了类似的东西(带有一些额外的 css/js)

但我无法将其实现为表单小部件

【问题讨论】:

你到底在纠结什么? 可能相关:***.com/questions/4707192/… 滑块未绑定到表单输入,因此您必须将回调添加到滑块stop 事件并相应地填充一些隐藏的输入,以便表单可以发布此数据。要呈现这样的东西及其所需的脚本,您需要制作一个自定义表单小部件并覆盖其render 方法以添加这个额外的 DIV、隐藏输入和脚本标记 将这一切变成一个单独的硬编码会容易得多。您所需要的只是将表单字段值作为隐藏输入,每当它更改时,都需要使用此滑块小部件中的值填充。 谢谢,我没有想到用javascript填充的隐藏输入。 【参考方案1】:

感谢@YujiTomita 提供 cmets,这是我的解决方案:

基本思想是生成一个带有隐藏输入的表单集,其中之一是调用一些 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。

【讨论】:

以上是关于Django - 时间范围小部件的主要内容,如果未能解决你的问题,请参考以下文章

将范围滑块小部件移植到 PyQt5

如何引用似乎超出范围的小部件 - 改编的 kivy/examples/demo/images

django安装使用xadmin

mainloop() 的代码范围是多少?

设置 Zend Dojo TextTimeBox 的时间范围

以自定义形式使用 Django 时间/日期小部件