Code

Opened 7 years ago

Closed 6 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 robvdl 6 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 7 years ago by Simon G. <dev@…>

  • Component changed from Uncategorized to django.newforms
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

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 6 years ago by robvdl

  • Has patch set
  • Resolution invalid deleted
  • Status changed from closed to reopened

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 6 years ago by robvdl

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

comment:3 Changed 6 years ago by jacob

  • Triage Stage changed from Unreviewed to Accepted

comment:4 Changed 6 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 6 years ago by robvdl

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 6 years ago by mtredinnick

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 6 years ago by SmileyChris

  • Resolution set to duplicate
  • Status changed from reopened to closed

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

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.