自定義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())

 界面如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章