gpt4 book ai didi

Django 自定义小部件将 IntegerField 拆分为模型表单中的小时和秒字段

转载 作者:行者123 更新时间:2023-12-02 05:21:08 25 4
gpt4 key购买 nike

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

最佳答案

您想使用 MultiWidget .我建议您覆盖该字段本身。看看 docs for creating custom fields .

如果可以,可能值得将数据存储为表示 python timedelta 的 float .您可能想在您的字段中添加一些自定义方法。如果您想对您的字段进行任何计算,使用 timedelta 将很有用。

您可能想阅读一下 form validation也是。

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

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 可以最好地解决这个问题。

关于Django 自定义小部件将 IntegerField 拆分为模型表单中的小时和秒字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13824266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com