Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django自定义小部件,用于在模型表单中将整型字段拆分为小时和秒字段_Django_Custom Widgets - Fatal编程技术网

Django自定义小部件,用于在模型表单中将整型字段拆分为小时和秒字段

Django自定义小部件,用于在模型表单中将整型字段拆分为小时和秒字段,django,custom-widgets,Django,Custom Widgets,我将持续时间存储为整数字段中的分钟数。在我的前端表单(模型表单)中,我想将输入拆分为一个字段(分钟)和一个字段(小时)。我还希望能够使用InLineFormset。这能以一种好的方式完成吗?我可以使用javascript,但对我来说,这似乎不是一个好的解决方案,或者是吗?您想使用javascript。我建议您重写字段本身。看一看这张照片 如果可以的话,将数据存储为一个浮点数表示一个变量可能是值得的。您可能需要向字段中添加一些自定义方法。如果要对字段进行任何计算,则使用timedelta将非常有用

我将持续时间存储为整数字段中的分钟数。在我的前端表单(模型表单)中,我想将输入拆分为一个字段(分钟)和一个字段(小时)。我还希望能够使用InLineFormset。这能以一种好的方式完成吗?我可以使用javascript,但对我来说,这似乎不是一个好的解决方案,或者是吗?

您想使用javascript。我建议您重写字段本身。看一看这张照片

如果可以的话,将数据存储为一个浮点数表示一个变量可能是值得的。您可能需要向字段中添加一些自定义方法。如果要对字段进行任何计算,则使用timedelta将非常有用

你可能还想继续读下去

我已经在Django 1.4上使用基于浮点的自定义字段测试了以下小时、分钟、秒多窗口小部件-

from datetime import timedelta
from django import forms
from django.db import models
from django.core import exceptions, validators


def validate_timedelta(value):
    if not isinstance(value, timedelta):
        raise exceptions.ValidationError('A valid time period is required')


class SplitHoursMinsWidget(forms.widgets.MultiWidget):

    def __init__(self, *args, **kwargs):
        widgets = (
            forms.TextInput(),
            forms.TextInput(),
            forms.TextInput(),
        )
        super(SplitHoursMinsWidget, self).__init__(widgets, *args, **kwargs)

    def decompress(self, value):
        if value:
            return [value.seconds // 3600, (value.seconds // 60) % 60,
                    value.seconds % 60]
        return [None, None, None]

    def format_output(self, rendered_widgets):
        return ("HH:MM:SS " + rendered_widgets[0] + ":" + rendered_widgets[1] +
                 ":" + rendered_widgets[2])

    def value_from_datadict(self, data, files, name):
        hours_mins_secs = [
            widget.value_from_datadict(data, files, name + '_%s' % i)
            for i, widget in enumerate(self.widgets)]
        try:
            time_delta = (timedelta(hours=float(hours_mins_secs[0])) +
                          timedelta(minutes=float(hours_mins_secs[1])) +
                          timedelta(seconds=float(hours_mins_secs[2])))
        except ValueError:
            return None
        else:
            return time_delta


class TimeDeltaFormField(forms.Field):

    widget = SplitHoursMinsWidget


class TimeDeltaField(models.Field):

    __metaclass__ = models.SubfieldBase

    description = "Field to hold a python timedelta object"

    default_validators = [validate_timedelta, ]

    def to_python(self, value):
        if value in validators.EMPTY_VALUES or isinstance(value, timedelta):
            return value
        try:
            return timedelta(seconds=float(value))
        except:
            raise exceptions.ValidationError('A valid time period is required')

    def get_prep_value(self, value):
        return float(value.days * 86400 + value.seconds)

    def get_internal_type(self):
        return 'FloatField'

    def formfield(self, **kwargs):
        defaults = {'form_class': TimeDeltaFormField}
        defaults.update(kwargs)
        return super(TimeDeltaField, self).formfield(**defaults)

值得注意的是,这并没有提供任何有用的输入级验证(可以在分钟和秒输入元素中输入超过60)。也许用javascript可以最好地解决这个问题。

谢谢!我将仔细查看MultiWidget链接。关于timedelta:与我的IntegerField存储分钟相比,您如何看待使用timedelta的性能?我正在建立一个训练日志,其中会有很多求和。我认为这不应该是一个问题(我认为int计算的速度将是它的两倍,但我怀疑你是否真的需要对此进行优化-它不太可能成为你应用程序中的瓶颈)。@LordNelson我已经为一个基本字段添加了代码,该字段使用了小时、分钟的浮点,secs小部件。这应该是相当简单的调整小时和秒或整数基域。太好了!再次感谢你。这是完美的运动成绩(我打算将其存储在我的训练日志中),我也会将其用于我的练习注册。我只需要决定是更改字段以适合您的解决方案,还是更改您的解决方案以用于整数基字段。