Чтобы настроить способ визуализации поля, вам также необходимо определить виджет.
Следующий код показывает некоторые обязанности виджетов в django:
- рендеринг тега формы (суперкласс TextInput позаботится об этом)
- форматировать значение для отображения внутри поля формы.
здесь есть ошибка: класс значения может варьироваться, поскольку вы можете отображать очищенные значения, поступающие из поля, или неочищенные данные, поступающие из формы POST. Следовательно, проверьте, есть ли у нас числовое значение в _format_value; если это строка, просто оставьте ее как есть.
- сообщить, изменилось ли значение по сравнению с исходными данными. Очень важно, когда вы используете формы со значениями по умолчанию.
Обратите внимание, что код виджета основан на widgets.TimeInput из исходного кода django, что помогает быть последовательным.
from django import forms
from django.forms import widgets
from django.forms.util import ValidationError
class HourWidget(widgets.TextInput):
def _format_value(self, value):
if isinstance(value, float) or isinstance(value, int):
import math
hours = math.floor(value)
minutes = (value - hours) * 60
value = "%d:%02d" % (hours, minutes)
return value
def render(self, name, value, attrs=None):
value = self._format_value(value)
return super(HourWidget, self).render(name, value, attrs)
def _has_changed(self, initial, data):
return super(HourWidget, self)._has_changed(self._format_value(initial), data)
class HourField(forms.Field):
widget = HourWidget
def clean(self, value):
super(HourField, self).clean(value)
import re
match = re.match("^([0-9]{1,2}):([0-9]{2})$", value)
if not match:
raise ValidationError("Please enter a valid hour ( ex: 12:34 )")
groups = match.groups()
hour = float(groups[0])
minutes = float(groups[1])
if minutes >= 60:
raise ValidationError("Invalid value for minutes")
return hour + minutes/60
Обратите внимание, что 1:20 становится 1:19, что связано с потерей точности, вызванной использованием поплавка. Возможно, вы захотите изменить тип данных, если не хотите терять точность.