Opened 9 years ago

Closed 9 years ago

#5027 closed (duplicate)

cannot initial the selectdatewidget value in newforms

Reported by: anonymous Owned by: Jacob
Component: Forms Version: master
Severity: Keywords: newforms SelectDateWidget
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: UI/UX:

Description

cannot initial the selectdatewidget value in newforms:

class DateForm(forms.form): 
   date_field = forms.DateField?( widget=extras.SelectDateWidget()) 

the form do not initial the date field value

data = {"date_field" : "2007-04-07"} 
form = DateForm(initial=data) 

Attachments (1)

widgets.diff (592 bytes) - added by Rob van der Linde 9 years ago.
Cast value to a string, in case it was a datetime type

Download all attachments as: .zip

Change History (8)

comment:1 Changed 9 years ago by Simon G. <dev@…>

Component: Uncategorizeddjango.newforms
Resolution: invalid
Status: newclosed

can you double check this? I'm unable to recreate it:

In [1]: from django import newforms as forms

In [2]: class DateForm(forms.Form):
   ...:     date_field = forms.DateField()        
   ...:

In [5]: f = DateForm(initial={'date_field':'2007-02-10'})

In [6]: f
Out[6]: <__main__.DateForm object at 0x1227e50>

In [7]: f.as_ul()
Out[7]: u'<li><label for="id_date_field">Date field:</label> <input type="text" name="date_field" value="2007-02-10" id="id_date_field" /></li>'


In [9]: from django.newforms.extras.widgets import SelectDateWidget

In [10]: class DateForm2(forms.Form):
   ...:        date_field = forms.DateField(widget=SelectDateWidget)
   ...:

In [12]: g = DateForm2(initial={'date_field':'2007-02-10'})

In [13]: g.as_ul()
Out[13]: u'<li><label for="id_date_field">Date field:</label> <select name="date_field_month">\n<option value="1">January</option>\n<option value="2" selected="selected">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n<select name="date_field_day">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10" selected="selected">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n<select name="date_field_year">\n<option value="2007" selected="selected">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n<option value="2010">2010</option>\n<option value="2011">2011</option>\n<option value="2012">2012</option>\n<option value="2013">2013</option>\n<option value="2014">2014</option>\n<option value="2015">2015</option>\n<option value="2016">2016</option>\n</select></li>'

What version of Django are you on?

comment:2 Changed 9 years ago by Rob van der Linde

Has patch: set
Resolution: invalid
Status: closedreopened

I came across this bug too, and it took me a while to root out the problem and see where it was actually going wrong. I was using a custom model field derived directly of DateField
(SelectDateField), here is my code:

class SelectDateField(models.DateField):
	def __init__(self, *args, **kwargs):
		if 'years' in kwargs:
			self.years = kwargs['years']
			del(kwargs['years'])
		else:
			self.years = range(this_year - 10, this_year + 10)
		self.years.append(self.years[-1] + 1)
		super(SelectDateField, self).__init__(*args, **kwargs)

	def formfield(self, **kwargs):
		defaults = {'widget': widgets.SelectDateWidget(years=self.years)}
		defaults.update(kwargs)
		return super(SelectDateField, self).formfield(**defaults)

	def get_internal_type(self):
		return 'DateField'

My code would save dates to the database no problem, but not retrieve them. It took me a while to realize that the actual problem was because I was deriving my custom model field directly of DateField, it was passing a datetime type to SelectDateWidget's render function, instead of the selected string type. I was able to verify this, by putting some temp testing code in SelectDateWidget's render function.

In the end, the patch was very simple, cast value to a string before doing any operations such as split on it. This patch shouldn't break any previous behaviour from what I can see, so hopefully it's ok to include.

Changed 9 years ago by Rob van der Linde

Attachment: widgets.diff added

Cast value to a string, in case it was a datetime type

comment:3 Changed 9 years ago by Jacob

Triage Stage: UnreviewedAccepted

comment:4 Changed 9 years ago by Jacob

Patch needs improvement: set

I can't figure out where this patch is supposed to be applied; can you please upload a valid patch? See http://www.djangoproject.com/documentation/contributing/#patch-style if you're not sure how to do this.

comment:5 Changed 9 years ago by Rob van der Linde

That's would be because I didn't know how to do an "svn diff", I simply had django svn in one folder on my hard drive, and my fixed file in another folder and manually ran the "diff" command from the command line.

Basically it's in newforms/extras/widgets.py line 35, change

value = datetime.date(*map(int, value.split('-')))

to

value = datetime.date(*map(int, str(value).split('-')))

Sorry, the diff file doesn't seem to have path info in it.

comment:6 Changed 9 years ago by Malcolm Tredinnick

Hold on.. this doesn't look right. If 'value' is already a datetime instance, converting it to a string so that you can split it up, convert the pieces into ints and then back into a datetime instance is a lot more work than necessary. The right fix would be to check if it's a basestring and if so do the splitting part, otherwise just skip down to the line that extracts the pieces from the datetime.

comment:7 Changed 9 years ago by Chris Beaven

Resolution: duplicate
Status: reopenedclosed

Which is what #5917 does. I'll mark as a dupe of that.

Note: See TracTickets for help on using tickets.
Back to Top