问题描述
我在Django项目中显示了一个表单,并且表单字段之一是DateTimeInput
小部件,其定义为:
I have a form displayed in my Django project, and one of the form fields is a DateTimeInput
widget, defined with:
presentation_date = mDateTimeField(required=False, label="Presentation date", widget=forms.DateTimeInput(format='%d/%m/%Y %H:%M'))
此小部件当前显示从去年年初到今年末(01/01/2016- 31/12/2017)之间的所有日期.但是,在去年年底,这引起了一些问题,因为这意味着用户无法选择今年年初的日期.我想做的是将窗口小部件中可供选择的日期范围延长一年(即新范围为01/01/2016- 31/12/2018).
This widget currently displays all dates between the start of last year to the end of this year (01/01/2016- 31/12/2017). However, at the end of last year this caused some issues, as it meant that users were unable to select dates for the beginning of this year. What I want to do is extend the range of the dates available for selection in the widget by one year (i.e the new range would be 01/01/2016- 31/12/2018).
我知道可以使用表单验证来执行此操作(例如,通过编写诸如clean_presentation_date()
之类的视图并在该视图中执行验证,但这无法解决我遇到的问题-当前,日期为01/01/2016之前或2017年12月31日之后(在datetimepicker
日历中显示,当用户在表单中选择该字段时显示),因此日期无法显示.正是我想要的功能,但是我只想更改执行日期的值,以便至少始终可以选择整个下一日历年.
I understand that it is possible to do this using form validation (for example, by writing a view such as clean_presentation_date()
and performing the validation inside that view, but this won't solve the issue I'm having- as currently, dates before 01/01/2016 or after 31/12/2017 (displayed in the datetimepicker
calendar that's shown when the user selects the field in the form) are 'greyed out' and it is not possible to select them. This is exactly the functionality that I want, but I just want to change the values of the dates on which it is performed, so that at least the whole of the next calendar year is always selectable.
我搜索了maxDate
& forms.py
文件中的minDate
变量,在其中定义了具有此字段的表单,但是找不到任何看起来像是什么的东西,这限制了哪些日期可供选择,哪些日期无法选择.
I have searched for maxDate
& minDate
variables within the forms.py
file where the form with this field is defined, but can't find anything that looks like it is what's restricting which dates are available to be selected, and which are not selectable.
显示带有此表单的页面的view
定义为:
The view
that's showing the page with this form on it is defined with:
def concept(request, project_id):
project = Project.objects.prefetch_related('budget_versions').get(id=project_id)
deposit = Deposit.objects.get_or_create(project=project)[0]
presentations = project.budget_versions.select_related('meeting').prefetch_related('budget_items', 'cci_items', 'presenters').filter(version_number__isnull=False).annotate(vn=F('version_number') * -1).order_by('presentation_date', 'created', '-vn')
end_details = EndDetails.objects.get_or_create(project=project)[0]
presentation_formset = BudgetPresentationFormset(prefix="presentations", instance=project, queryset=presentations)
drawing_formset = DrawingUploadFormset(prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created'))
context = {
'project': project,
'presentations': presentations,
'presentation_formset': presentation_formset,
'drawing_formset': drawing_formset,
'deposit_form': DepositInfoForm(instance=deposit),
'ended_form': EndDetailsForm(instance=end_details),
'budget_notes_form': BudgetNotesForm(instance=project.budget_overview),
}
我正在查看的特定form
是在forms.py
中定义的presentations
:
The particular form
I'm looking at is the presentations
one, defined in forms.py
:
class FirstPresentationForm(ValidatedForm):
""" UNUSED """
who_presenting = forms.CharField()
details = forms.CharField(required=False, label='Original option costed')
presentation_date = mDateTimeField(required=False, label="Presentation date", widget=forms.DateTimeInput(format='%d/%m/%Y %H:%M')) #ERF(19/12/2016 @ 1210) Remove 'datetimepicker' from field..., attrs=({'class':'datetimepicker'})))
class Meta:
model = Budget
fields = ('presentation_date','who_presenting','details')
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance', {})
project = instance.project
who_presenting = [pe.employee.id for pe in project.assigned.select_related('employee').filter(role=Role.P)]
#Make into an array with two employee IDs, or None. If two results were found, they will already be in the right format
if len(who_presenting)==1:
who_presenting.append(None)
elif not who_presenting:
who_presenting = None
if instance.presentation_date:
pres_meeting, created = Meeting.objects.get_or_create(project=project, purpose='6')
self.pres_meeting_id = pres_meeting.id
self.pres_meeting_creator = pres_meeting.event_creator or ''
if created:
pres_meeting.date = instance.presentation_date
pres_meeting.save()
initial = kwargs.get('initial', {})
initial={
'who_presenting': who_presenting,
}
kwargs['initial'] = initial
super(FirstPresentationForm, self).__init__(*args, **kwargs)
self.fields['who_presenting'] = AutoFlexiSelect(model='e', required=False, choices=get_choices('DESIGN_EMPLOYEE_CHOICES'), current_id=who_presenting, label="Who is presenting")
self.fields['presentation_date'].widget.attrs.update({'data-meeting-id': getattr(self,'pres_meeting_id', ''), 'data-meeting-creator': getattr(self,'pres_meeting_creator', '')})
def save(self, commit=True):
project = self.instance.project
data = self.cleaned_data
try: ProjectEmployee.objects.filter(project=project, role=Role.P).delete() #Delete current records, if any, to prevent build up on editing this field
except ObjectDoesNotExist: pass
if data['who_presenting']:
designers = data['who_presenting']
# Get the ids from the form field (received as a string)
designers = [re.sub('\D+', '', s) for s in designers.split(',')]
who_presenting_1 = Employee.objects.get(id=designers[0])
who_presenting_2 = designers[1] #If only one employee in selected choice, this will be None
if who_presenting_2: who_presenting_2 = Employee.objects.get(id=designers[1]) #If two employees in selected choice, sets the second one
pe = ProjectEmployee(project=project, employee=who_presenting_1, role=Role.P)
pe.save()
if who_presenting_2: #If a second designer, delete as well
pe = ProjectEmployee(project=project, employee=who_presenting_2, role=Role.P)
pe.save()
if 'presentation_date' in self.changed_data:
from events.models import refresh_group_cache
print '************'
pres_meeting = Meeting.objects.get(project=project, purpose='6')
self.instance.meeting = pres_meeting
self.instance.save()
print 'Updating date', data['presentation_date'], pres_meeting.id
pres_meeting.date = data['presentation_date']
pres_meeting.save()
refresh_group_cache(pres_meeting.event_creator.calendar_id, pres_meeting.date.year, pres_meeting.date.month, pres_meeting.event_id, pres_meeting)
return super(FirstPresentationForm, self).save(commit=commit)
我尝试将max_date
设置为presentation_date
变量的属性,但似乎没有此名称的属性/属性...
I have tried passing/ setting max_date
as an attribute of the presentation_date
variable, but it doesn't appear to have an attribute/ property by this name...
如何指定特定日期作为此widget
的maxDate
,以便用户能够选择直到明年12月的日期,而不是直到今年12月的日期?
How can I specify a particular date as this widget
's maxDate
, so that the user is able to select dates up until December of next year, rather than just up until December of this year?
修改
在forms.py
中也定义了使用widget
的mDateTimeField
,其内容如下:
The mDateTimeField
that's using the widget
is also defined in forms.py
, with:
class mDateTimeField(forms.DateTimeField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('input_formats', DATE_INPUT_FORMATS)
super(mDateTimeField, self).__init__(*args, **kwargs)
推荐答案
这应为您提供帮助:
widgets = {
'start_date': forms.DateInput(attrs={
'class':'datepicker', 'data-min': YOUR_MIN_DATE,
'data-max': YOUR_MAX_DATE}),
}
用法:
minDate: $(this).data('min'),
maxDate: $(this).data('max'),
这篇关于Django表单DateTimeInput小部件-如何指定最大日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!