class Meta: dateTimeOptions = {'format': 'dd/mm/yyyy HH:ii', 'autoclose': True} model = Derivacion fields = ('beneficiario', 'prestacion', 'fecha_hora', 'motivo', 'observacion') labels = { 'beneficiario': 'Beneficiario', 'prestacion': 'Prestacion', 'fecha_hora': 'Fecha y hora', 'motivo': 'Motivo', 'observacion': 'Observaciones' } widgets = { 'beneficiario': forms.Select(attrs={'class': 'form-control'}), 'prestacion': forms.Select(attrs={'class': 'form-control'}), 'fecha_hora': widgets.DateTimeWidget(attrs={ 'id': 'id_fecha', 'class': 'form-control' }, bootstrap_version=3, options=dateTimeOptions), 'motivo': forms.TextInput(attrs={'class': 'form-control'}), 'observacion': forms.Textarea(attrs={'class': 'form-control'}) }
class Meta: dateTimeOptions = {'format': 'dd/mm/yyyy HH:ii', 'autoclose': True} model = ActividadExtension fields = ('titulo', 'descripcion', 'fecha', 'presupuesto', 'disertante', 'capacidad') labels = { 'titulo': 'Título', 'descripcion': 'Descripción', 'fecha': 'Fecha', 'presupuesto': 'Presupuesto', 'disertante': 'Disertante', 'capacidad': 'Capacidad' } widgets = { 'titulo': forms.TextInput(attrs={'class': 'form-control'}), 'descripcion': forms.Textarea(attrs={'class': 'form-control'}), 'fecha': widgets.DateTimeWidget(attrs={ 'id': 'id_fecha', 'class': 'form-control' }, bootstrap_version=3, options=dateTimeOptions), 'presupuesto': forms.TextInput(attrs={'class': 'form-control'}), 'disertante': forms.Select(attrs={'class': 'form-control'}), 'capacidad': forms.TextInput(attrs={'class': 'form-control'}) }
class Meta: """Model to be used from within this form.""" model = launch_models.Launch fields = ('identifier', 'date') widgets = { 'date': datetime_widgets.DateTimeWidget(usel10n=True, bootstrap_version=3) }
class Meta: model = Event fields = '__all__' exclude = [ 'author', 'creation_time', 'open', 'result', ] widgets = { 'start_time': ext_widgets.DateTimeWidget(attrs={id: 'id_start_time'}, usel10n=True, bootstrap_version=3), 'end_time': ext_widgets.DateTimeWidget(attrs={id: 'id_end_time'}, usel10n=True, bootstrap_version=3) }
class DataSelectionForm(forms.Form): """Form for selection of dataset parameters, such as time and variables. """ variables = forms.MultipleChoiceField( label='Variables:', required=True, widget=forms.CheckboxSelectMultiple(attrs={ # 'data-mini': 'true' })) timezone = forms.TypedChoiceField(required=True, label="time zone", coerce=timezone_coerce) # pickerPosition: bottom-right, bottom-left # popup calendar box is to lower left or right of textbox & icon start_time = forms.DateTimeField( widget=dt_widgets.DateTimeWidget(bootstrap_version=3, options={ 'format': 'yyyy-mm-dd hh:ii', 'clearBtn': 0, 'todayBtn': 0, 'pickerPosition': 'bottom-right' })) # this should only be enabled if the end time of the project # is in the future. track_real_time = forms.BooleanField(required=False, initial=False) # choices: (value, label) time_length = FloatWithChoiceField(choices=[( str(i), str(i), ) for i in TIME_LEN_CHOICES], label='Time length', min_value=0) time_length_units = forms.ChoiceField(choices=[( c, c, ) for c in TIME_UNITS_CHOICES], initial=TIME_UNITS_CHOICES[0], label='') stations = forms.MultipleChoiceField( label='Stations', required=False, widget=forms.CheckboxSelectMultiple(attrs={ # 'data-mini': 'true' })) soundings = forms.MultipleChoiceField( label='Soundings', required=False, widget=forms.CheckboxSelectMultiple(attrs={ # 'data-mini': 'true' })) # Variable to plot on Y axis in sounding plot. Only # required for a sounding yvariable = forms.ChoiceField( label='Variable to plot on Y axis in sounding plot', required=False) def __init__(self, *args, dataset=None, request=None, **kwargs): """Set choices for time zone from dataset. Raises: """ super().__init__(*args, **kwargs) self.dataset = dataset self.request = request self.clean_method_altered_data = False if len(dataset.timezones.all()) > 0: self.fields['timezone'].choices = \ [(v.tz, str(v.tz)) for v in dataset.timezones.all()] else: proj = dataset.project self.fields['timezone'].choices = \ [(v.tz, str(v.tz)) for v in proj.timezones.all()] def set_variable_choices(self, variables): """Set the available variables in this form. Args: variables: list of variable names. """ # choices: (value, label) self.fields['variables'].choices = sorted( [(n, n) for n in variables], key=lambda x: str.lower(x[0])) # print("choices=%s" % repr(self.fields['variables'].choices)) def set_yvariable_choices(self, variables): """Set the available Y axis variables in this form. Args: variables: list of variable names. """ # choices: (value, label) self.fields['yvariable'].choices = sorted( [(n, n) for n in variables], key=lambda x: str.lower(x[0])) def set_station_choices(self, station_names): """Set the available stations in this form. Args: station_names: list of station names """ # choices: (value, label) choices = [] if len(station_names) > 0: # a station name of None means no variables without a station # if station_names[0] is not None: # choices.append((0, "null")) # # choices.append(("0", "null")) # choices.extend([('{}'.format(i+1), n) for i, n in \ # enumerate(station_names[1:])]) choices.extend([(i, n) for i, n in enumerate(station_names)]) self.fields['stations'].choices = choices def clean(self): """Check the user's selections for correctness. If the user has selected a start_time outside of the dataset's time period, the value of cleaned_data['start_time'] will be updated to be within the dataset period. A message will be added to the request to indicate what has happened. Likewise, set cleaned_data['track_real_time'] to False if the current time is after the end of the dataset. If either field has been altered, set self.clean_method_altered_data=True so that the view method knows to generate a new form with the altered values. Returns: A dictionary of cleaned_data. As of django 1.7 this is no longer required. """ cleaned_data = super().clean() timezone = cleaned_data.get('timezone') if not timezone: raise forms.ValidationError('timezone not found') tnow = datetime.datetime.now(timezone) post_real_time = tnow > self.dataset.end_time if post_real_time: if cleaned_data['track_real_time']: self.clean_method_altered_data = True cleaned_data['track_real_time'] = False self.fields['track_real_time'].widget.attrs['disabled'] = True # the time fields are in the browser's timezone. Use those exact fields, # but interpret them in the dataset timezone start_time = self.get_cleaned_start_time() if not start_time: raise forms.ValidationError('start time not found') try: if start_time < self.dataset.get_start_time(): msg = "chosen start time: {} is earlier than " \ "dataset start time, resetting to {}".format( start_time.isoformat(), self.dataset.get_start_time().astimezone(timezone).isoformat()) if self.request: messages.warning(self.request, msg) # self.add_error('start_time', forms.ValidationError(msg)) start_time = self.dataset.get_start_time().astimezone(timezone) cleaned_data['start_time'] = start_time.replace(tzinfo=None) self.clean_method_altered_data = True except nc_exc.NoDataException: self.add_error( 'start_time', forms.ValidationError("dataset start time not available")) tunits = cleaned_data.get('time_length_units') if not tunits or not tunits in TIME_UNITS_CHOICES: raise forms.ValidationError( 'invalid time units: {}'.format(tunits)) if 'time_length' not in cleaned_data: self.add_error('time_length', forms.ValidationError('invalid time length')) tdelta = self.get_cleaned_time_length() if not tdelta or tdelta.total_seconds() <= 0: msg = "time length must be positive" self.add_error('time_length', forms.ValidationError(msg)) if cleaned_data['track_real_time']: start_time = (tnow - tdelta).astimezone(timezone) cleaned_data['start_time'] = start_time.replace(tzinfo=None) self.clean_method_altered_data = True elif start_time > self.dataset.get_end_time(): new_start_time = (self.dataset.get_end_time() - tdelta).astimezone(timezone) msg = "chosen start time: {} is later than " \ "dataset end time: {}, resetting to {}".format( start_time.isoformat(), self.dataset.get_end_time().astimezone(timezone).isoformat(), new_start_time.isoformat()) if self.request: messages.warning(self.request, msg) # self.add_error('start_time', forms.ValidationError(msg)) start_time = new_start_time cleaned_data['start_time'] = start_time.replace(tzinfo=None) self.clean_method_altered_data = True if 'variables' not in cleaned_data or len( cleaned_data['variables']) == 0: self.add_error('variables', forms.ValidationError('no variables selected')) if self.dataset.dset_type == "sounding": if 'soundings' not in cleaned_data or \ len(cleaned_data['soundings']) == 0: self.add_error('soundings', forms.ValidationError('no soundings selected')) return cleaned_data def get_cleaned_time_length(self): """Return the time period length chosen by the user. Returns: a datetime.timedelta. """ if 'time_length' not in self.cleaned_data or \ 'time_length_units' not in self.cleaned_data: return None tlen = self.cleaned_data['time_length'] # normalized to float tunits = self.cleaned_data['time_length_units'] # string return get_time_length(tlen, tunits) def get_cleaned_start_time(self): """Return a timezone aware start_time from cleaned_data of the form, or None if 'start_time' is not found in cleaned_data. Returns: A datetime.datetime, within the timezone of cleaned_data['timezone']. """ if 'start_time' not in self.cleaned_data or \ 'timezone' not in self.cleaned_data: return None start_time = self.cleaned_data['start_time'] timezone = self.cleaned_data['timezone'] # start_time in cleaned data at this point is timezone aware, but # with the browser's timezone """ A datetime object d is aware if d.tzinfo is not None and d.tzinfo.utcoffset(d) does not return None. If d.tzinfo is None, or if d.tzinfo is not None but d.tzinfo.utcoffset(d) returns None, d is naive. if start_time.tzinfo == None or start_time.tzinfo.utcoffset(start_time) == None: _logger.debug("form clean start_time is timezone naive") else: _logger.debug("form clean start_time is timezone aware") """ # the time fields are in the browser's timezone. Use those exact fields, # but interpret them in the dataset timezone return timezone.localize(start_time.replace(tzinfo=None)) def too_much_data(self, exc): """Set an error on this form. """ self.errors['__all__'] = self.error_class([repr(exc)]) def no_data(self, exc): """Set an error on this form. """ self.errors['__all__'] = self.error_class([repr(exc)]) def data_not_available(self, exc): """Set an error on this form. """ self.errors['__all__'] = self.error_class([repr(exc)])