To customize how the field is rendered, you also need to define a widget.
The following code shows some of the responsibilities of widgets in django:
- render the form tag (the superclass "TextInput" will take care of this)
- formats the value to display inside the form field. there is useful information here: the class of values may differ, because you can display cleared values coming from the field, or raw data coming from the POST form. Therefore, a test if we have a numerical value in _format_value; if it's a string, just leave it as it is.
- Please indicate if the value has changed from the original data. Very important when using forms with default values.
, 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, , . , , .