2017-01-03 2 views
0

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 widgetmaxDate, 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) 

Répondre

0

Cela devrait vous aider:

widgets = { 
    'start_date': forms.DateInput(attrs={ 
     'class':'datepicker', 'data-min': YOUR_MIN_DATE, 
     'data-max': YOUR_MAX_DATE}), 
} 

Utilisation:

minDate: $(this).data('min'), 
maxDate: $(this).data('max'), 
+0

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

+0

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 –

+0

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