Django中的自定义日期小部件?

0 投票
2 回答
628 浏览
提问于 2025-04-18 10:19

在我现在的应用程序中,它是基于Python和Django的,我创建了一个自定义的日期控件。

from datetime import date
from django.forms import widgets

class DateSelectorWidget(widgets.MultiWidget):
    def __init__(self, attrs=None):
        # create choices for months, years
        # example below, the rest snipped for brevity.
        years = [(year, year) for year in range(1945, 2016)]        
        months = [(1,'Jan'),(2,'Feb')]
        _widgets = (        
            widgets.Select(attrs=attrs, choices=months),
            widgets.Select(attrs=attrs, choices=years),
        )
        super(DateSelectorWidget, self).__init__(_widgets, attrs)

    def decompress(self, value):
        if value:
            return [value.month, value.year]
        return [None, None]

    def format_output(self, rendered_widgets):
        return u''.join(rendered_widgets)

    def value_from_datadict(self, data, files, name):
        datelist = [
            widget.value_from_datadict(data, files, name + '_%s' % i)
            for i, widget in enumerate(self.widgets)]
        try:
            D = date(day=1, month=int(datelist[0]),
                    year=int(datelist[1]))
        except ValueError:
            return ''
        else:
            return str(D) 

当表单加载时,它工作得很好(返回日期对象),但是当我提交表单并且有一些字段留空时,我就会遇到以下错误。

Caught AttributeError while rendering: 'str' object has no attribute 'month'

Request Method:     POST
Request URL:    
Django Version:     1.3.1
Exception Type:     TemplateSyntaxError
Exception Value:    

Caught AttributeError while rendering: 'str' object has no attribute 'month'

Exception Location:     /var/www/stacks/django-apps/kkk/apps/oooomonth_year.py in decompress, line 21

2 个回答

0

这个问题出现的原因是,当表单提交的数据被绑定时(但因为验证信息或其他问题没有存入数据库)。

def decompress(self, value):
        if value:
            return [value.month, value.year]
        return [None, None]

上面的方法只在日期存入数据库时处理日期。但是当表单没有成功提交时,它就像一个“字符串对象”一样工作。所以你需要用下面定义的方法来更新上面的方法:

def decompress(self, value):
        if value:
            import types
            try:
                if type(value) == types.StringType:
                    from datetime import datetime as dt
                    tmp_date = dt.strptime(value, '%Y-%m-%d')
                    return [tmp_date.month, tmp_date.year]
                else:
                    return [value.month, value.year]
            except:
                raise
        else:
            return [None, None]

现在这个方法可以处理两种情况,无论表单是否成功提交。

0

你在这里遇到了一个错误,

def decompress(self, value):
        if value:
            return [value.month, value.year]
        return [None, None]

value 这个对象没有叫做 month 的属性。如果你想知道这个 value 对象有什么属性,可以用 print dir(value) 来查看。在这里,value 是一个字符串。

更新:

可以检查一下这个属性 hasattr(value, 'month')。希望这对你有帮助。

撰写回答