Home » Custom Writing » Writing custom widgets django cast

Writing custom widgets django cast

Writing custom widgets django cast It was actually surprisingly easy

Every so often you run into a situation where Django ‘s built-in form fields and widgets just don’t meet your needs. I ran into this the other day when creating a credit card processing form. I wanted an easy way for the user to enter the expiration month and date of their card, but the tools provided by django only gave me a single text field and the option to use a javascript date picker. Neither of those was quite what I wanted, I just wanted two selects that would allow the user to pick the month and the year, as on pretty much every credit card form you’ve ever filled out online. The obvious option would be to make two separate fields on your model, one for month, and one for year. But I don’t really like that option. I would much rather have both selects show up on the same line, which is not the behavior you’d get with two separate fields. So I decided to write a custom widget and field to accomplish this. It was actually surprisingly easy to do. Probably the most difficult part was coming up with a decent way to populate the selects with worthwhile options. I’m not entirely pleased with the route I took there, but it’s easy enough to change later. Here’s my code: from django import forms import datetime class MonthYearWidget(forms.MultiWidget): “”” A widget that splits a date into Month/Year with selects. “”” def __init__(self, attrs=None): months = ( (’01’, ‘Jan (01)’), (’02’, ‘Feb (02)’), (’03’, ‘Mar (03)’), (’04’, ‘Apr (04)’), (’05’, ‘May (05)’), (’06’, ‘Jun (06)’), (’07’, ‘Jul (07)’), (’08’, ‘Aug (08)’), (’09’, ‘Sep (09)’), (’10’, ‘Oct (10)’), (’11’, ‘Nov (11)’), (’12’, ‘Dec (12)’), ) year = int(datetime.date.today().year) year_digits = range(year, year+10) years = [(year, year) for year in year_digits] widgets = (forms.Select(attrs=attrs, choices=months), forms.Select(attrs=attrs, choices=years)) super(MonthYearWidget, self).__init__(widgets, attrs) def decompress(self, value): if value: return [value.month, value.year] return [None, None] def render(self, name, value, attrs=None): try: value = datetime.date(month=int(value[0]), year=int(value[1]), day=1) except: value = ” return super(MonthYearWidget, self).render(name, value, attrs) class MonthYearField(forms.MultiValueField): def compress(self, data_list): if data_list: return datetime.date(year=int(data_list[1]), month=int(data_list[0]), day=1) return datetime.date.today() Simple, no?

Writing custom widgets django cast selects show up on the

The results end up looking like so:

Josh Ourisman 2006-2012


Share this: