From 9a6f1362b7cee897421fff89c53862558e6c73ca Mon Sep 17 00:00:00 2001 From: "grzegorz.prokopczyk@gmail.com" Date: Mon, 2 Mar 2015 13:12:39 +0100 Subject: [PATCH] time range form field --- qcg/fields.py | 60 +++++++++++++++++++++++++++++-- qcg/forms.py | 6 ++-- qcg/templates/qcg/job_new.html | 4 +-- qcg/templates/qcg/time_range_field.html | 14 ++++++++ 4 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 qcg/templates/qcg/time_range_field.html diff --git a/qcg/fields.py b/qcg/fields.py index 3702aad..3e5ec44 100644 --- a/qcg/fields.py +++ b/qcg/fields.py @@ -1,11 +1,65 @@ -from django.forms import ChoiceField, MultipleChoiceField +# coding=utf-8 +from datetime import timedelta +from django import forms +from django.core.exceptions import ValidationError -class PredefinedChoiceField(ChoiceField): +class PredefinedChoiceField(forms.ChoiceField): def valid_value(self, value): # any value is valid return True -class MultiplePredefinedChoiceField(MultipleChoiceField, PredefinedChoiceField): +class MultiplePredefinedChoiceField(forms.MultipleChoiceField, PredefinedChoiceField): pass + + +class TimeRangeWidget(forms.MultiWidget): + def decompress(self, value): + if not value: + return [0, TimeRangeField.SECONDS] + + seconds = value.seconds + 86400 * value.days + + if seconds % 60 != 0: + return [seconds, TimeRangeField.SECONDS] + elif seconds % 3600 != 0: + return [seconds / 60, TimeRangeField.MINUTES] + elif seconds % 86400 != 0: + return [seconds / 3600, TimeRangeField.HOURS] + else: + return [seconds / 86400, TimeRangeField.DAYS] + + +class TimeRangeField(forms.MultiValueField): + SECONDS, MINUTES, HOURS, DAYS = range(4) + UNIT_CHOICES = ( + (SECONDS, u"Sekund"), + (MINUTES, u"Minut"), + (HOURS, u"Godzin"), + (DAYS, u"Dni"), + ) + + value = forms.IntegerField(min_value=0) + unit = forms.ChoiceField(choices=UNIT_CHOICES) + + widget = TimeRangeWidget(widgets=(value.widget, unit.widget)) + + def __init__(self, *args, **kwargs): + super(TimeRangeField, self).__init__((self.value, self.unit), *args, **kwargs) + + def compress(self, data_list): + try: + unit = int(data_list[1]) + if unit == self.SECONDS: + return timedelta(seconds=data_list[0]) + elif unit == self.MINUTES: + return timedelta(minutes=data_list[0]) + elif unit == self.HOURS: + return timedelta(hours=data_list[0]) + elif unit == self.DAYS: + return timedelta(days=data_list[0]) + else: + raise ValidationError(u"Nieprawidłowa jednostka") + except ValueError: + raise ValidationError(u"Nieprawidłowa jednostka") diff --git a/qcg/forms.py b/qcg/forms.py index 83a053a..7b11d13 100644 --- a/qcg/forms.py +++ b/qcg/forms.py @@ -4,7 +4,7 @@ from django.core.validators import RegexValidator from django.template.defaultfilters import capfirst from pyqcg.utils import TaskStatus -from qcg.fields import PredefinedChoiceField, MultiplePredefinedChoiceField +from qcg.fields import PredefinedChoiceField, MultiplePredefinedChoiceField, TimeRangeField from qcg.models import Task, Allocation @@ -120,7 +120,7 @@ class JobDescriptionForm(forms.Form): queue = PredefinedChoiceField(choices=QUEUE_CHOICES, label=u"Kolejka", required=False) procs = forms.IntegerField(label=u"Liczba procesów", min_value=0, required=False) nodes = forms.CharField(label=u"Topologia węzłów", max_length=10, validators=[nodes_validator], required=False) - wall_time = forms.IntegerField(label=u"Wall time (s)", min_value=0, required=False) # TODO duration field + wall_time = TimeRangeField(label=u"Wall time", required=False) memory = forms.IntegerField(label=u"Pamięć (MB)", min_value=0, required=False) memory_per_slot = forms.IntegerField(label=u"Pamięci per proces (MB)", min_value=0, required=False) @@ -136,7 +136,7 @@ class JobDescriptionForm(forms.Form): not_after = forms.DateTimeField(label=u"Nie później niż", required=False) not_before = forms.DateTimeField(label=u"Nie wcześniej niż", required=False) - deadline = forms.IntegerField(label=u"Deadline (s)", min_value=0, required=False) # TODO duration field + deadline = TimeRangeField(label=u"Deadline", required=False) reservation = forms.CharField(label=u"Rezerwacja", max_length=100, required=False) monitoring = forms.BooleanField(label=u"Portal QCG-Monitoring", required=False) diff --git a/qcg/templates/qcg/job_new.html b/qcg/templates/qcg/job_new.html index d1e5de6..37a4fc5 100644 --- a/qcg/templates/qcg/job_new.html +++ b/qcg/templates/qcg/job_new.html @@ -123,7 +123,7 @@ {% bootstrap_field form.queue layout="horizontal" %} {% bootstrap_field form.procs layout="horizontal" %} {% bootstrap_field form.nodes layout="horizontal" form_group_class="form-group collapse" %} - {% bootstrap_field form.wall_time layout="horizontal" %} + {% include 'qcg/time_range_field.html' with field_name='wall_time' field=form.wall_time %} {% bootstrap_field form.memory layout="horizontal" %} {% bootstrap_field form.memory_per_slot layout="horizontal" %} @@ -161,7 +161,7 @@
{% bootstrap_field form.not_before layout="horizontal" %} {% bootstrap_field form.not_after layout="horizontal" %} - {% bootstrap_field form.deadline layout="horizontal" %} + {% include 'qcg/time_range_field.html' with field_name='deadline' field=form.deadline %} {% bootstrap_field form.reservation layout="horizontal" form_group_class="form-group collapse" %}
diff --git a/qcg/templates/qcg/time_range_field.html b/qcg/templates/qcg/time_range_field.html new file mode 100644 index 0000000..c9570c5 --- /dev/null +++ b/qcg/templates/qcg/time_range_field.html @@ -0,0 +1,14 @@ +
+ +
+ +
+
+ +
+
\ No newline at end of file -- 1.7.9.5