`
maplye
  • 浏览: 111765 次
  • 来自: ...
社区版块
存档分类
最新评论

自定义form field和widget(YearMonthField)

阅读更多

django的form将界面的展示和数据校验转换做了很好的封装,并且提供了很多的一些Field和Widget,昨天在做一个项目时有一个月报表的功能,查询的时候需要选择某年某月,于是参照一些网站信息,写了一个YearMonthField.

#创建年月表单控件   
class YearMonthWidget(forms.MultiWidget):
    """
    A widget that splits a date into Month/Year with selects.
    """
    def __init__(self, attrs=None,year_range=None,month_range=None):
        
        YEARS = year_range or range(2000,2021)
        MONTHES = month_range or range(1,13)

        years = map(lambda x: (x,x), YEARS )
        months = map(lambda x:(x,x>9 and x or '0'+str(x)), MONTHES )

        widgets = (forms.Select(attrs=attrs, choices=years),forms.Select(attrs=attrs, choices=months))
        super(YearMonthWidget, self).__init__(widgets, attrs)
    
    def decompress(self, value):
        if value:
            return [value.year, value.month]
        return [None, None]

class YearMonthField(forms.MultiValueField):
    widget=YearMonthWidget
    def __init__(self,*args,**kwargs):
        fields = (
                forms.IntegerField( required=True),
                forms.IntegerField( required=True),
                )
        super(YearMonthField, self).__init__(fields, *args,**kwargs )
    
    def compress(self, data_list):
        if data_list:
            return datetime.date(year=int(data_list[0]), month=int(data_list[1]), day=1)
        return datetime.date.today()

 

代码说明:

主要是继承MultiWidget和MultiValueField

关键是分别有两个方法需要重写,decompress和compress.

widget中需要将数据解压缩成list和其中的widgets对应.

field中需要将list转成所需要的数据格式,如YearMonthField的datetime类型.

 

使用如下:

import datetime
class ReportMonthForm(Form):
    month = YearMonthField(label='查询月份',initial=datetime.date.today())

 界面如下:

  • 大小: 6.2 KB
1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics