Django cond_choices=[(%.2d“%i,%.2d“%i)表示以自我秒为单位的i] 第二个选项[0:0]=[('',--')] 本地属性['id']=self.second\u字段%id_ select\u html=select(choices=second\u choices).render(self.second\u字段%name,second\u val,local\u attrs) output.append(选择html) 如果自我十二小时: #如果给我们一个初始值,确保选择了正确的meridiem get。 如果meridiem_val和meridiem_val.以('p')开头: 梅里迪安大学选项=[('p.m.,'p.m.),('a.m.,'a.m.),('''-')] 其他: 梅里迪安大学选项=[('','-'),('a.m.,'a.m.,('p.m.,'p.m.)] 本地属性['id']=本地属性['id']=self.meridiem\u字段%id_ 选择html=select(选项=meridiem\u选项)。呈现(self.meridiem\u字段%name,meridiem\u val,本地属性) output.append(选择html) 选择_html=u'\n'.连接(输出) 返回标记为安全(“%s”)%(选择html) def id_用于_标签(self,id_u): 返回%s\u小时%id_ id_代表_标签=classmethod(id_代表_标签) def value_from_datadict(自身、数据、文件、名称): meridiem=data.get(self.meridiem_字段%name) h=数据.get(self.hour_字段%name,0)#hour m=数据.get(self.minute_字段%name,0)#分钟 s=data.get(self.second_字段%name,0)#second 如果有(在(h,m)中表示在('',无)): 一无所获 #注:如果meridiem为无,则假设为24小时 如果meridiem不是无: 如果meridiem.lower()以('p')和int(h)!=12: h=(整数(h)+12)%24 elif meridiem.lower().startswith('a')和int(h)==12: h=0 如果(int(h)==0或h)和m和s: 返回“%s:%s:%s%”(h,m,s) 返回数据.get(名称,无) #这是分割日期和时间的小部件。 类友好型PlitDateTimeWidget(MultiWidget): """ 将日期时间输入拆分为两个框的小部件 并使用更好的时间选择器 """ date\u format=DateInput.format time\u format=TimeInput.format 定义初始值(self,attrs=None,date\u format=None,time\u format=None,seven\u hr=True): 如果日期格式为: self.date\u格式=date\u格式 如果时间单位格式: self.time\u格式=time\u格式 widgets=(DateInput(attrs=attrs,format=self.date\u格式), 选择TimeWidget(十二小时=十二小时)) super(FriendlySplitDateTimeWidget,self)。\uuuu init\uuuu(widgets,attrs) def解压缩(自身,值): 如果值: 如果isinstance(值、基串): value=datetime.strtime(值,“%Y-%m-%d%H:%m:%S”) 返回[value.date(),value.time().replace(微秒=0)] 返回[无,无]
以下是我使用的拆分日期/时间小部件: 首先,时间小部件。有很多代码。我在这里复制/粘贴,因此可能有您不需要的导入。我把它保存在一个名为“custom\u form\u widgets.py”的文件中 在底部,您将看到我的“FriendlySplitDateTimeWidget”类,您可以在表单中使用它。时间可以基于24小时或12小时的时钟。日期字段呈现为文本输入,但您可以轻松添加您选择的JavaScript弹出日历实现。希望这对你有所帮助Django cond_choices=[(%.2d“%i,%.2d“%i)表示以自我秒为单位的i] 第二个选项[0:0]=[('',--')] 本地属性['id']=self.second\u字段%id_ select\u html=select(choices=second\u choices).render(self.second\u字段%name,second\u val,local\u attrs) output.append(选择html) 如果自我十二小时: #如果给我们一个初始值,确保选择了正确的meridiem get。 如果meridiem_val和meridiem_val.以('p')开头: 梅里迪安大学选项=[('p.m.,'p.m.),('a.m.,'a.m.),('''-')] 其他: 梅里迪安大学选项=[('','-'),('a.m.,'a.m.,('p.m.,'p.m.)] 本地属性['id']=本地属性['id']=self.meridiem\u字段%id_ 选择html=select(选项=meridiem\u选项)。呈现(self.meridiem\u字段%name,meridiem\u val,本地属性) output.append(选择html) 选择_html=u'\n'.连接(输出) 返回标记为安全(“%s”)%(选择html) def id_用于_标签(self,id_u): 返回%s\u小时%id_ id_代表_标签=classmethod(id_代表_标签) def value_from_datadict(自身、数据、文件、名称): meridiem=data.get(self.meridiem_字段%name) h=数据.get(self.hour_字段%name,0)#hour m=数据.get(self.minute_字段%name,0)#分钟 s=data.get(self.second_字段%name,0)#second 如果有(在(h,m)中表示在('',无)): 一无所获 #注:如果meridiem为无,则假设为24小时 如果meridiem不是无: 如果meridiem.lower()以('p')和int(h)!=12: h=(整数(h)+12)%24 elif meridiem.lower().startswith('a')和int(h)==12: h=0 如果(int(h)==0或h)和m和s: 返回“%s:%s:%s%”(h,m,s) 返回数据.get(名称,无) #这是分割日期和时间的小部件。 类友好型PlitDateTimeWidget(MultiWidget): """ 将日期时间输入拆分为两个框的小部件 并使用更好的时间选择器 """ date\u format=DateInput.format time\u format=TimeInput.format 定义初始值(self,attrs=None,date\u format=None,time\u format=None,seven\u hr=True): 如果日期格式为: self.date\u格式=date\u格式 如果时间单位格式: self.time\u格式=time\u格式 widgets=(DateInput(attrs=attrs,format=self.date\u格式), 选择TimeWidget(十二小时=十二小时)) super(FriendlySplitDateTimeWidget,self)。\uuuu init\uuuu(widgets,attrs) def解压缩(自身,值): 如果值: 如果isinstance(值、基串): value=datetime.strtime(值,“%Y-%m-%d%H:%m:%S”) 返回[value.date(),value.time().replace(微秒=0)] 返回[无,无],django,django-forms,django-widget,Django,Django Forms,Django Widget,以下是我使用的拆分日期/时间小部件: 首先,时间小部件。有很多代码。我在这里复制/粘贴,因此可能有您不需要的导入。我把它保存在一个名为“custom\u form\u widgets.py”的文件中 在底部,您将看到我的“FriendlySplitDateTimeWidget”类,您可以在表单中使用它。时间可以基于24小时或12小时的时钟。日期字段呈现为文本输入,但您可以轻松添加您选择的JavaScript弹出日历实现。希望这对你有所帮助 import re from datetime impo
import re
from datetime import datetime
from django import forms
from django.conf import settings
from django.forms.widgets import Widget, Select, MultiWidget, DateInput, TimeInput
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
from django.utils.text import truncate_words
# Attempt to match many time formats:
# Example: "12:34:56 P.M." matches:
# ('12', '34', ':56', '56', 'P.M.', 'P', '.', 'M', '.')
# ('12', '34', ':56', '56', 'P.M.')
# Note that the colon ":" before seconds is optional, but only if seconds are omitted
time_pattern = r'(\d\d?):(\d\d)(:(\d\d))? *((a{1}|A{1}|p{1}|P{1})(\.)?(m{1}|M{1})(\.)?)?$'
RE_TIME = re.compile(time_pattern)
# The following are just more readable ways to access re.matched groups:
HOURS = 0
MINUTES = 1
SECONDS = 3
MERIDIEM = 4
class SelectTimeWidget(Widget):
"""
A Widget that splits time input into <select> elements.
Allows form to show as 24hr: <hour>:<minute>,
or as 12hr: <hour>:<minute> <am|pm>
Also allows user-defined increments for minutes/seconds
"""
hour_field = '%s_hour'
minute_field = '%s_minute'
second_field = '%s_second'
meridiem_field = '%s_meridiem'
twelve_hr = False # Default to 24hr.
def __init__(self, attrs=None, hour_step=None, minute_step=None, second_step=None, twelve_hr=False):
'''
hour_step, minute_step, second_step are optional step values for
for the range of values for the associated select element
twelve_hr: If True, forces the output to be in 12-hr format (rather than 24-hr)
'''
self.attrs = attrs or {}
if twelve_hr:
self.twelve_hr = True # Do 12hr (rather than 24hr)
if hour_step and twelve_hr:
self.hours = range(1, 13, hour_step)
elif hour_step: # 24hr, with stepping.
self.hours = range(0, 24, hour_step)
elif twelve_hr: # 12hr, no stepping
self.hours = range(1, 13)
else: # 24hr, no stepping
self.hours = range(0, 24)
if minute_step:
self.minutes = range(0, 60, minute_step)
else:
self.minutes = range(0, 60)
if second_step:
self.seconds = range(0, 60, second_step)
else:
self.seconds = range(0, 60)
def render(self, name, value, attrs=None):
try: # try to get time values from a datetime.time object (value)
hour_val, minute_val, second_val = value.hour, value.minute, value.second
if self.twelve_hr:
if hour_val >= 12:
meridiem_val = 'p.m.'
else:
meridiem_val = 'a.m.'
else:
meridiem_val = None
except AttributeError:
hour_val = minute_val = second_val = meridiem_val = ''
if isinstance(value, basestring):
match = RE_TIME.match(value)
if match:
time_groups = match.groups();
hour_val = int(time_groups[HOURS]) % 24 # force to range(0-24)
minute_val = int(time_groups[MINUTES])
if time_groups[SECONDS] is None:
second_val = 0
else:
second_val = int(time_groups[SECONDS])
# check to see if meridiem was passed in
if time_groups[MERIDIEM] is not None:
meridiem_val = time_groups[MERIDIEM]
else: # otherwise, set the meridiem based on the time
if self.twelve_hr:
if hour_val >= 12:
meridiem_val = 'p.m.'
else:
meridiem_val = 'a.m.'
else:
meridiem_val = None
if self.twelve_hr:
# Modify the hour value appopriately for 12-hour clocks.
if hour_val > 12 and hour_val < 24:
hour_val = hour_val % 12
elif hour_val == 0:
hour_val = 12
output = []
if 'id' in self.attrs:
id_ = self.attrs['id']
else:
id_ = 'id_%s' % name
# NOTE: for times to get displayed correctly, the values MUST be converted to unicode
# When Select builds a list of options, it checks against Unicode values
if hour_val != '':
hour_val = u"%.2d" % hour_val
if minute_val != '':
minute_val = u"%.2d" % minute_val
if second_val != '':
second_val = u"%.2d" % second_val
hour_choices = [("%.2d" % i, "%.2d" % i) for i in self.hours]
hour_choices[0:0] = [('', '--')]
local_attrs = self.build_attrs(id=self.hour_field % id_)
select_html = Select(choices=hour_choices).render(self.hour_field % name, hour_val, local_attrs)
output.append(select_html)
minute_choices = [("%.2d" % i, "%.2d" % i) for i in self.minutes]
minute_choices[0:0] = [('', '--')]
local_attrs['id'] = self.minute_field % id_
select_html = Select(choices=minute_choices).render(self.minute_field % name, minute_val, local_attrs)
output.append(select_html)
second_choices = [("%.2d" % i, "%.2d" % i) for i in self.seconds]
second_choices[0:0] = [('', '--')]
local_attrs['id'] = self.second_field % id_
select_html = Select(choices=second_choices).render(self.second_field % name, second_val, local_attrs)
output.append(select_html)
if self.twelve_hr:
# If we were given an initial value, make sure the correct meridiem get's selected.
if meridiem_val and meridiem_val.startswith('p'):
meridiem_choices = [('p.m.', 'p.m.'), ('a.m.', 'a.m.'), ('', '--')]
else:
meridiem_choices = [('', '--'), ('a.m.', 'a.m.'), ('p.m.', 'p.m.')]
local_attrs['id'] = local_attrs['id'] = self.meridiem_field % id_
select_html = Select(choices=meridiem_choices).render(self.meridiem_field % name, meridiem_val, local_attrs)
output.append(select_html)
selects_html = u'\n'.join(output)
return mark_safe('<div class="friendly_time_widget">%s</div>') % (selects_html)
def id_for_label(self, id_):
return '%s_hour' % id_
id_for_label = classmethod(id_for_label)
def value_from_datadict(self, data, files, name):
meridiem = data.get(self.meridiem_field % name)
h = data.get(self.hour_field % name, 0) # hour
m = data.get(self.minute_field % name, 0) # minute
s = data.get(self.second_field % name, 0) # second
if any(falsy in (h, m) for falsy in ('', None)):
return None
#NOTE: if meridiem IS None, assume 24-hr
if meridiem is not None:
if meridiem.lower().startswith('p') and int(h) != 12:
h = (int(h) + 12) % 24
elif meridiem.lower().startswith('a') and int(h) == 12:
h = 0
if (int(h) == 0 or h) and m and s:
return '%s:%s:%s' % (h, m, s)
return data.get(name, None)
#This is the widget that splits the date and time.
class FriendlySplitDateTimeWidget(MultiWidget):
"""
A Widget that splits datetime input into two <input type="text"> boxes
and uses a better time selector
"""
date_format = DateInput.format
time_format = TimeInput.format
def __init__(self, attrs=None, date_format=None, time_format=None, twelve_hr=True):
if date_format:
self.date_format = date_format
if time_format:
self.time_format = time_format
widgets = (DateInput(attrs=attrs, format=self.date_format),
SelectTimeWidget(twelve_hr=twelve_hr))
super(FriendlySplitDateTimeWidget, self).__init__(widgets, attrs)
def decompress(self, value):
if value:
if isinstance(value, basestring):
value = datetime.strptime(value, '%Y-%m-%d %H:%M:%S')
return [value.date(), value.time().replace(microsecond=0)]
return [None, None]
重新导入
从日期时间导入日期时间
来自django导入表单
从django.conf导入设置
从django.forms.widgets导入小部件,选择,多小部件,日期输入,时间输入
从django.template.loader导入渲染到字符串
从django.utils.safestring导入标记_safe
从django.utils.text导入截断单词
#尝试匹配多种时间格式:
#示例:“下午12:34:56”匹配:
#(‘12’、‘34’、‘56’、‘56’、‘下午’、‘P’、‘M’、’)
#(‘12’、‘34’、‘56’、‘56’、‘P.M.)
#请注意,秒之前的冒号“:”是可选的,但仅当省略秒时
时间模式=r'(\d\d?):(\d\d)(:(\d\d))*({1}a{1}p{1}p{1})(\)?(m{1}m{1})(\)?)?$”
重新编译(时间模式)
#以下是访问重新匹配的组的更易读的方法:
小时=0
分钟=1
秒=3
梅里迪姆=4
类SelectTimeWidget(小部件):
"""
将时间输入拆分为元素的小部件。
允许窗体显示为24小时::,
或作为12小时:
还允许用户定义分钟/秒的增量
"""
小时\字段=“%s\u小时”
分钟字段='%s\u分钟'
第二个字段=“%s\u秒”
meridiem_字段=“%s_meridiem”
十二小时=假#默认为24小时。
定义初始值(self,attrs=None,hour\u step=None,minute\u step=None,second\u step=None,seven\u hr=False):
'''
小时步长、分钟步长、秒步长是的可选步长值
用于关联的select元素的值范围
12小时:如果为真,则强制输出为12小时格式(而不是24小时)
'''
self.attrs=attrs或{}
如果十二小时:
self.12_hr=True#做12小时(而不是24小时)
如果一小时一步和十二小时:
self.hours=范围(1,13,小时步)
elif hour#u步进:24小时,带步进。
self.hours=范围(0,24,hour\u步)
埃利夫十二小时:十二小时,禁止踩踏
self.hours=范围(1,13)
否则:#24小时,禁止踩踏
self.hours=范围(0,24)
如果是分钟步骤:
self.minutes=范围(0,60,分步)
其他:
self.minutes=范围(0,60)
如果第二步:
self.seconds=范围(0,60,秒级)
其他:
self.seconds=范围(0,60)
def render(自身、名称、值、属性=无):
try:#尝试从datetime.time对象(值)获取时间值
小时,分钟,秒=value.hour,value.minute,value.second
如果自我十二小时:
如果小时值>=12:
梅里迪安•瓦尔=‘下午’
其他: