问题
forms.py
DATE_INPUT_FORMAT = (
('%d/%m/%Y','%m/%d/%Y')
)
class ReportForm(forms.ModelForm):
manual_date = forms.DateField(input_formats = DATE_INPUT_FORMAT,
widget=forms.DateInput(format = '%d/%m/%Y'))
1.Date format should change depend upon the value in database,if value is in db,it shows the 1st format and for none ,else part is executing.
2.Formats are changing depends upon the condition.
3.I am facing problem here,if the input format is of this (%m/%d/%Y),on form post the value of date gets interchange and saved in database.If the given date is 07/06/2013 -->7th june 2013,after form post it is viewed in the field as 06/07/2013 -->6th july 2013.It is not working properly.
Need help to solve this issue.
Thanks
回答1:
Here is another way to change the input format dynamically
forms.py:
class ReportForm(forms.Form):
manual_time = forms.TimeField(input_formats = TIME_INPUT_FORMAT,
widget=forms.TimeInput(attrs={'size':'8','class':'time_field'}))
manual_date = forms.DateField(widget=forms.DateInput(
attrs={'size':'15', 'id':'datepicker'}))
def __init__(self, *args, **kwargs):
# Get the date_format if present in parameters
date_format = None
if 'date_format' in kwargs:
date_format = kwargs.pop('date_format')
super(ReportForm, self).__init__(*args, **kwargs)
# Dynamically set input date format
if date_format:
self.fields['manual_date'].input_formats = (date_format, )
views.py
def when(request):
"""To view and save report time and date
"""
if not 'report_id' in request.session:
return redirect('incident.views.new_report')
report_id = request.session['report_id']
report = Report.objects.get(pk=report_id)
try:
settings = Settings.objects.get(user=request.user)
dateformat = settings.date_format
timeformat = settings.time_format
except:
dateformat = False
timeformat = False
date = None
time = None
if not report.manual_date:
report.manual_date = datetime.datetime.now()
if not report.manual_time:
report.manual_time = datetime.datetime.now()
manual_date = datetime.datetime.now()
if int(dateformat):
date_format = '%m/%d/%Y'
datelabel = "Date(mm/dd/yyyy)"
createddate = report.created_date_time.strftime('%b %d %Y')
else:
date_format = '%d/%m/%Y'
datelabel = "Date(dd/mm/yyyy)"
createddate = report.created_date_time.strftime('%d %b %Y')
date = report.manual_date.strftime(date_format)
if int(timeformat):
time = report.manual_time.strftime('%H:%M')
timelabel = "Time(24hour)"
createdtime = report.created_date_time.strftime('%H:%M')
else:
time = report.manual_time.strftime('%I:%M %p')
timelabel = "Time(12hour)"
createdtime = report.created_date_time.strftime('%I:%M %p')
if request.method == 'POST':
reportform = ReportForm(request.POST, date_format=date_format)
if reportform.is_valid():
report.manual_date = reportform.cleaned_data['manual_data']
report.manual_time = reportform.cleaned_data['manual_time']
report.user = request.user
report.save()
if not 'next' in request.POST:
return redirect('incident.views.report_confirm')
return redirect('incident.views.media')
else:
reportform = ReportForm(instance=report, initial={'manual_date':date, 'manual_time':time})
leftbar = common_leftbar(request, report_id)
return render_to_response('incident/when.html',
{
'newreport_menu': True,
'when_tab': True,
'reportform': reportform,
'datelabel':datelabel,
'timelabel':timelabel,
'createddate':createddate,
'createdtime':createdtime,
'incident': report,
'leftbar':leftbar
},
context_instance=RequestContext(request))
The key here to change the input_formats
attribute of DateField dynamically when you create the form. So when you submit the form, you should pass the date_format
and the default DateField should convert your date fine. You will have to adapt this code into yours as I have assumed some of things in the code above.
回答2:
Simplest solution is create factory for presenting form:
def ReportFormFactory(date_format):
class ReportForm(forms.ModelForm):
manual_date = forms.DateField(
input_formats=[date_format],
widget=forms.DateInput(format=date_format)
)
return ReturnForm
and then in view:
if int(dateformat):
ReportForm = ReportFormFactory('%m/%d/%Y')
else:
ReportForm = ReportFormFactory('%d/%m/%Y')
dates should be changed to strings only at presention stage in widget, in other places left them as datetime or date objects
回答3:
I think you need to inherit DateField
and override strptime
method to do what you want.
class MyDateField(forms.DateField):
def strptime(self, value, format):
# Ignore format and continue by your dateformat
if int(dateformat):
date = datetime.datetime.strptime(force_str(value), '%m/%d/%Y').date()
else:
date = datetime.datetime.strptime(force_str(value), '%d/%m/%Y').date()
# Output for debugging
print "Raw input: '%s', dateformat: %s, date: %s" % (value, dateformat, date)
return date
class ReportForm(forms.ModelForm):
manual_date = MyDateField(widget=forms.DateInput(format='%d/%m/%Y',
attrs='size':'15', 'id':'datepicker', 'readonly':'readonly'}))
I do not know where the dateformat
flag comes from, so it may cause some troubles.
Note: I just noticed that the widget is read-only. Why do you want to add it into the form? It would be much simpler if you just show the date in the template.
Note2: There is several things you should be aware of: You have d/m/Y
format set in your widget and in datepicker, these are likely to cause troubles. You should pass date instances as initial values in your form, that should work better.
回答4:
Ah, the old date formatting problem. Have you considered storing all your dates in a [timestamp format[(Are unix timestamps the best way to store timestamps?) and then formatting them correctly when displaying/saving.
I suggest you always display the date in a certain format, and make sure the date comes back from the view in the same format. For an input form, giving variety isn't worth the hassle.
回答5:
Instead of reinventing the wheel, you should rely on Django > 1.2 capability to localize date format. Django handles outputting date in localized format as well as handling form submits with localized dates out of the box. You just need to give the user capability to set his/her desired locale and Django would handle different formats by itself. https://docs.djangoproject.com/en/1.4/topics/i18n/formatting/
回答6:
Try does your code is more clearly:
reportform = ReportForm(request.POST or None,
instance=report,
initial={'manual_date':date, 'manual_time':time})
if reportform.is_valid():
report = reportform.save(commit=False)
report.user = request.user
report.save()
What format sent your client after save form?
来源:https://stackoverflow.com/questions/17123054/data-format-value-changes-in-database