I have a django app that tracks activities that can benefit a classroom. Using the django examples, I was able to build a form to enter this data. But when I try to add widgets to that form, things get tricky.
What I want is a calendar widget that lets the user enter the 'activity_date' field using a widget. If I use Admin interface. The AdminDateWidget works fine. however. This particular user isn't allowed access to the admin interface so I need a different way to present this widget. Also I couldn't figure out how to make the bring the admin widget over into non-admin pages. So I tried a custom widget.
This is the first custom widget I've built, so I'm not quite sure what is supposed to be going on here.
Any Expert Advice? How do I get my date widget to work?
# The Model
class Activity(models.Model):
activity_date = models.DateField()
activity_type = models.CharField(max_length=50, choices=ACTIVITY_TYPES)
activity_description = models.CharField(max_length=200)
activity_duration= models.DecimalField(decimal_places=2, max_digits=4)
est_attendance = models.IntegerField("Estimated attendance")
# The Form
class ActivityForm(forms.ModelForm):
# The following line causes lockup if enabled.
# With the DateTimeWidget removed, the form functions correctly except that there is no widget.
#activity_date = forms.DateField(label=_('Date'), widget=DateTimeWidget) ##!!! Point of Error !!!
class Meta:
model = Activity
fields = ('activity_date', 'activity_type', 'activity_description', 'activity_duration', 'est_attendance')
def __init__(self, *args, **kwargs):
super(ActivityForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
edit_aid = kwargs.get('edit_aid', False)
# On a different approach, the following also didn't work.
#self.fields['activity_date'].widget = widgets.AdminDateWidget()
# The Widget
# Example referenced: http://djangosnippets.org/snippets/391/
calbtn = u""" <button id="calendar-trigger">...</button>
<img src="%s/site_media/images/icon_calendar.gif" alt="calendar" id="%s_btn" style="cursor: pointer; border: 1px solid #8888aa;"
title="Select date and time"
onmouseover="this.style.background='#444444';" onmouseout="this.style.background=''" />
<script type="text/javascript">
Calendar.setup({
trigger : "calendar-trigger",
inputField : "%s"
});
</script>"""
class DateTimeWidget(forms.widgets.TextInput):
dformat = '%Y-%m-%d %H:%M'
def render(self, name, value, attrs=None):
print "DTWgt render name=%s, value=%s" % name, value
if value is None: value = ''
final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
if value != '':
try:
final_attrs['value'] = \
force_unicode(value.strftime(self.dformat))
except:
final_attrs['value'] = \
force_unicode(value)
if not final_attrs.has_key('id'):
final_attrs['id'] = u'%s_id' % (name)
id = final_attrs['id']
jsdformat = self.dformat #.replace('%', '%%')
cal = calbtn % (settings.MEDIA_URL, id, id, jsdformat, id)
a = u'<input%s />%s' % (forms.util.flatatt(final_attrs), cal)
print "render return %s " % a
return mark_safe(a)
def value_from_datadict(self, data, files, name):
print "DTWgt value_from_datadict"
dtf = forms.fields.DEFAULT_DATETIME_INPUT_FORMATS
empty_values = forms.fields.EMPTY_VALUES
value = data.get(name, None)
if value in empty_values:
return None
if isinstance(value, datetime.datetime):
return value
if isinstance(value, datetime.date):
return datetime.datetime(value.year, value.month, value.day)
for format in dtf:
try:
return datetime.datetime(*time.strptime(value, format)[:6])
except ValueError:
continue
return None