【问题标题】:Django form split into two drop down (selects)Django 表单分成两个下拉列表(选择)
【发布时间】:2013-04-03 22:15:14
【问题描述】:

在我的表单中,我有 expiry_date....

expiry_date = forms.DateField()

到期日期必须采用 MMYY 格式,即 2013 年 12 月的 1213。不应包含 / 或字符。

但这在最终用户看来有点不妥。那么,是否可以在 Django 中添加两个选择框 1 代表月份,1 代表年份,然后以某种方式将它们重新组合在一起以在发布前再次创建 expiry_date?

即我希望我的用户看到月份和年份的下拉菜单,然后选择它。

这是我目前所拥有的......

CARD_CHOICES = [
    ('VISA', 'VISA'),
    ('MC', 'MasterCard'),
    ('DELTA', 'DELTA'),
    ('MAESTRO', 'Maestro'),
    ('UKE', 'Visa Electron'),
    ]

DATE_INPUT_FORMATS = ('MMYY',)
class OrderForm(forms.Form):
    """
    Order Form used to collect data ready for processing.
    """
    amount = forms.FloatField()
    expiry_date = forms.DateField(input_formats=DATE_INPUT_FORMATS)
    CSV = forms.CharField(max_length=3)
    card_type = forms.TypedChoiceField(choices=CARD_CHOICES, initial='VISA')

【问题讨论】:

    标签: python django django-forms


    【解决方案1】:

    你基本上需要MultiValueField

    这里是一个示例实现:django-creditcard app

    class ExpiryDateField(forms.MultiValueField):
        """
        Form field that validates credit card expiry dates.
        """
    
        default_error_messages = {
            'invalid_month': _(u'Please enter a valid month.'),
            'invalid_year': _(u'Please enter a valid year.'),
            'date_passed': _(u'This expiry date has passed.'),
        }
    
        def __init__(self, *args, **kwargs):
            today = date.today()
            error_messages = self.default_error_messages.copy()
            if 'error_messages' in kwargs:
                error_messages.update(kwargs['error_messages'])
            if 'initial' not in kwargs:
                # Set default expiry date based on current month and year
                kwargs['initial'] = today
            months = [(x, '%02d (%s)' % (x, date(2000, x, 1).strftime(MONTH_FORMAT))) for x in xrange(1, 13)]
            years = [(x, x) for x in xrange(today.year, today.year + 15)]
            fields = (
                forms.ChoiceField(choices=months, error_messages={'invalid': error_messages['invalid_month']}),
                forms.ChoiceField(choices=years, error_messages={'invalid': error_messages['invalid_year']}),
            )
            super(ExpiryDateField, self).__init__(fields, *args, **kwargs)
            self.widget = ExpiryDateWidget(widgets=[fields[0].widget, fields[1].widget])
    
        def clean(self, value):
            expiry_date = super(ExpiryDateField, self).clean(value)
            if date.today() > expiry_date:
                raise forms.ValidationError(self.error_messages['date_passed'])
            return expiry_date
    
        def compress(self, data_list):
            if data_list:
                try:
                    month = int(data_list[0])
                except (ValueError, TypeError):
                    raise forms.ValidationError(self.error_messages['invalid_month'])
                try:
                    year = int(data_list[1])
                except (ValueError, TypeError):
                    raise forms.ValidationError(self.error_messages['invalid_year'])
                try:
                    day = monthrange(year, month)[1] # last day of the month
                except IllegalMonthError:
                    raise forms.ValidationError(self.error_messages['invalid_month'])
                except ValueError:
                    raise forms.ValidationError(self.error_messages['invalid_year'])
                return date(year, month, day)
            return None
    

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多