Django SelectDateWidget to show only month and year

Is there any other widget or argument that will allow django to show or accept only the year and month instead of year, month and day?

Currently using SelectDateWidget.

+7
source share
3 answers

Here is a snippet here that sets the day to 1 (suppose you have a DateField so that you get this value, you need to get some day).

The code looks like this (just in case, Django fragments disappear):

 import datetime import re from django.forms.widgets import Widget, Select from django.utils.dates import MONTHS from django.utils.safestring import mark_safe __all__ = ('MonthYearWidget',) RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$') class MonthYearWidget(Widget): """ A Widget that splits date input into two <select> boxes for month and year, with 'day' defaulting to the first of the month. Based on SelectDateWidget, in django/trunk/django/forms/extras/widgets.py """ none_value = (0, '---') month_field = '%s_month' year_field = '%s_year' def __init__(self, attrs=None, years=None, required=True): # years is an optional list/tuple of years to use in the "year" select box. self.attrs = attrs or {} self.required = required if years: self.years = years else: this_year = datetime.date.today().year self.years = range(this_year, this_year+10) def render(self, name, value, attrs=None): try: year_val, month_val = value.year, value.month except AttributeError: year_val = month_val = None if isinstance(value, basestring): match = RE_DATE.match(value) if match: year_val, month_val, day_val = [int(v) for v in match.groups()] output = [] if 'id' in self.attrs: id_ = self.attrs['id'] else: id_ = 'id_%s' % name month_choices = MONTHS.items() if not (self.required and value): month_choices.append(self.none_value) month_choices.sort() local_attrs = self.build_attrs(id=self.month_field % id_) s = Select(choices=month_choices) select_html = s.render(self.month_field % name, month_val, local_attrs) output.append(select_html) year_choices = [(i, i) for i in self.years] if not (self.required and value): year_choices.insert(0, self.none_value) local_attrs['id'] = self.year_field % id_ s = Select(choices=year_choices) select_html = s.render(self.year_field % name, year_val, local_attrs) output.append(select_html) return mark_safe(u'\n'.join(output)) def id_for_label(self, id_): return '%s_month' % id_ id_for_label = classmethod(id_for_label) def value_from_datadict(self, data, files, name): y = data.get(self.year_field % name) m = data.get(self.month_field % name) if y == m == "0": return None if y and m: return '%s-%s-%s' % (y, m, 1) return data.get(name, None) 
+9
source

An example of the Python 3 widget is here https://djangosnippets.org/snippets/10522/ .

Usage example:

 class myForm(forms.Form): # ... date = forms.DateField( required=False, widget=MonthYearWidget(years=xrange(2004,2010)) ) 
0
source

Today I ran into the same problem and solved it by removing the day field through the css property and setting the value to 1 as the value for the day being cleared.

 #id_my_date_field_day-button { display: none; } 

I used ModelForm with UpdateView and therefore had the source data in my fields, which made life a little easier, because I always had a valid value for the day my_date_field.

0
source

All Articles