Trying to test SelectDateWidget as SelectMonthDayWidget on command line

eileen at themaii.org eileen at themaii.org
Mon Jun 3 15:18:36 EDT 2019


Hi,
I'm a newbie and I want to change the Django SelectDateWidget to SelectMonthDayWidget because I can't use the year in my application. I had been getting another error (which I don't recall right now) on the statement that started 'html['month']' so, I decided to convert it to command line to get a better picture of what's going on.
Unfotunately, now I get:
Traceback (most recent call last):
  File "SelectMDWidget.py", line 34, in <module>
    class SelectMonthDayWidget(month,day_ok):
TypeError: Error when calling the metaclass bases
    unicode() argument 2 must be string, not tuple

What am I doing wrong? I'm passing the class two strings...

"""
HTML Widget classes
"""
from __future__ import unicode_literals

import copy
import re
from itertools import chain

from django.conf import settings
from django.forms.widgets import Widget, Select
from django.templatetags.static import static

from django.utils import formats
from django.utils.dates import MONTHS
from django.utils.formats import get_format

from django.utils.safestring import mark_safe
from django.utils.six.moves import range
from django.utils.translation import ugettext_lazy, gettext_lazy as _

from django.utils.deprecation import (
    RemovedInDjango20Warning, RenameMethodsBase,
)
from django.utils.encoding import (
    force_str, force_text, python_2_unicode_compatible,
)

__all__ = ('SelectMonthDayWidget', )

day_ok = u''
month = u''

class SelectMonthDayWidget(month,day_ok):
    """
    A Widget that splits date input into three <select> boxes.

    This also serves as an example of a Widget that has more than one HTML
    element and hence implements value_from_datadict.
    """
    none_value = (0, '---')
    month_field = month #'%s_month'
    day_field = day_ok #'%s_day'
    select_widget = Select

    def __init__(self, attrs=None, months=None, empty_label=None):
        self.attrs = attrs or {}

        # Optional dict of months to use in the "month" select box.
        if months:
            self.months = months
        else:
            self.months = MONTHS

        # Optional string, list, or tuple to use as empty_label.
        if isinstance(empty_label, (list, tuple)):
            if not len(empty_label) == 3:
                raise ValueError('empty_label list/tuple must have 2 elements.')

            self.month_none_value = (0, empty_label[0])
            self.day_none_value = (0, empty_label[1])
        else:
            if empty_label is not None:
                self.none_value = (0, empty_label)

            self.month_none_value = self.none_value
            self.day_none_value = self.none_value

    @staticmethod
    def _parse_date_fmt():
        fmt = get_format('DATE_FORMAT')
        escaped = False
        for char in fmt:
            if escaped:
                escaped = False
            elif char == '\\':
                escaped = True
            elif char in 'bEFMmNn':
                yield 'month'
            elif char in 'dj':
                yield 'day'

    def render(self, name, value, attrs=None):
        try:
            month_val, day_val = value.month, value.day
        except AttributeError:
            month_val = day_val = None
            if isinstance(value, six.string_types):
                if settings.USE_L10N:
                    try:
                        input_format = get_format('DATE_INPUT_FORMATS')[0]
                        v = datetime.datetime.strptime(force_str(value), input_format)
                        month_val, day_val = v.month, v.day
                    except ValueError:
                        pass
                if year_val is None:
                    match = self.date_re.match(value)
                    if match:
                        month_val, day_val = [int(val) for val in match.groups()]
        html = {}
        choices = list(self.months.items())
        html['month'] = self.create_select(name, self.month_field, value, month_val, choices, self.month_none_value)
        choices = [(i, i) for i in range(1, 32)]
        html['day'] = self.create_select(name, self.day_field, value, day_val, choices, self.day_none_value)

        output = []
        for field in self._parse_date_fmt():
            output.append(html[field])
        return mark_safe('\n'.join(output))

    def id_for_label(self, id_):
        for first_select in self._parse_date_fmt():
            print ('1','%s_%s' % (id_, first_select))
            return '%s_%s' % (id_, first_select)
        else:
            print ('2','%s_month' % id_)
            return '%s_month' % id_
            
    def value_from_datadict(self, data, files, name):
        m = data.get(self.month_field % name)
        d = data.get(self.day_field % name)
        if m == d == "0":
            return None
        if m and d:
            if settings.USE_L10N:
                input_format = get_format('DATE_INPUT_FORMATS')[0]
                try:
                    date_value = datetime.date(int(y), int(m), int(d))
                except ValueError:
                    print ('3','%s-%s' % (m, d))
                    return '%s-%s' % (m, d)
                else:
                    date_value = datetime_safe.new_date(date_value)
                    return date_value.strftime(input_format)
            else:
                print ('4','%s-%s' % (m, d))
                return '%s-%s' % (m, d)
        return data.get(name)

    def value_omitted_from_data(self, data, files, name):
        return not any(
            ('{}_{}'.format(name, interval) in data)
            for interval in ('month', 'day')
        )

    def create_select(self, name, field, value, val, choices, none_value):
        if 'id' in self.attrs:
            id_ = self.attrs['id']
        else:
            id_ = 'id_%s' % name
        if not self.is_required:
            choices.insert(0, none_value)
        local_attrs = self.build_attrs(id=field % id_)
        s = self.select_widget(choices=choices)
        select_html = s.render(field % name, val, local_attrs)
        return select_html
        
SelectMonthDayWidget(u'Jan',u'31')



More information about the Python-list mailing list