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