J'ai une forme affichée dans mon projet Django, et l'un des champs de formulaire est un widget DateTimeInput
, défini par:Django crée un widget DateTimeInput - comment spécifier la date maximale?
presentation_date = mDateTimeField(required=False, label="Presentation date", widget=forms.DateTimeInput(format='%d/%m/%Y %H:%M'))
Ce widget affiche actuellement toutes les dates entre le début de l'année dernière à la fin de cette année (01/01/2016- 31/12/2017). Cependant, à la fin de l'année dernière, cela a causé quelques problèmes, car cela signifiait que les utilisateurs étaient incapables de choisir des dates pour le début de cette année. Ce que je veux faire est d'allonger d'un an la plage des dates disponibles pour la sélection dans le widget (c'est-à-dire que la nouvelle plage serait 01/01/2016- 31/12/2018). Je comprends qu'il est possible de le faire en utilisant la validation de formulaire (par exemple, en écrivant une vue telle que clean_presentation_date()
et en effectuant la validation à l'intérieur de cette vue, mais cela ne résoudra pas le problème que j'ai - comme actuellement , les dates antérieures au 01/01/2016 ou après le 31/12/2017 (affichées dans le calendrier datetimepicker
affiché lorsque l'utilisateur sélectionne le champ dans le formulaire) sont grisées et il n'est pas possible de les sélectionner. la fonctionnalité que je veux, mais je veux juste changer les valeurs des dates auxquelles il est effectué, de sorte qu'au moins l'ensemble de la prochaine année civile est toujours sélectionnable.
J'ai cherché maxDate
& minDate
variables dans le fichier forms.py
où le formulaire avec ce champ est défini, mais ne peut pas trouver quelque chose qui ressemble à ce qui restreint quelles dates sont disponibles pour être sélectionnés, et qui ne sont pas sélectionnables.
Le view
qui est montrant la page avec ce formulaire, il est défini par:
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),
}
Le form
particulier je regarde est le presentations
un, défini dans 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)
J'ai essayé de passer/définir max_date
comme un attribut de la variable presentation_date
, mais il ne semble pas avoir un attribut/propriété de ce nom ...
Comment puis-je spécifier une date particulière comme widget
maxDate
, de sorte que l'utilisateur puisse sélectionner des dates jusqu'au mois de décembre de l'année prochaine, plutôt que juste jusqu'en décembre de cette année?
Modifier
Le mDateTimeField
qui est à l'aide du widget
est également défini dans forms.py
, avec:
class mDateTimeField(forms.DateTimeField):
def __init__(self, *args, **kwargs):
kwargs.setdefault('input_formats', DATE_INPUT_FORMATS)
super(mDateTimeField, self).__init__(*args, **kwargs)
Merci pour votre réponse. Je ne suis pas sûr d'où je mettrais ça ...? Ai-je besoin de personnaliser la définition du 'widget' quelque part? J'utilise 'DateTimeInput', pas' DateInput' ... je ne sais pas si cela fait une différence ...? – someone2088
Oui, vous devez personnaliser votre widget. Et vous pouvez utiliser le code ci-dessus alors.Il suffit d'incorporer la même chose dans votre code –
Où puis-je personnaliser le widget? Cela ne fait-il pas partie des fonctionnalités intégrées de Django? Où pourrais-je mettre le code que vous avez écrit dans votre réponse? Dans la classe 'mDateTimeField' dans' forms.py', ou dans le paramètre de l'instance de formulaire que je crée dans 'view'? – someone2088