misc: use Django native split datetime field (#45108)
This commit is contained in:
parent
8e56a48b4f
commit
449805969f
|
@ -44,7 +44,7 @@ from chrono.agendas.models import (
|
|||
)
|
||||
|
||||
from . import widgets
|
||||
from .widgets import DateTimeWidget
|
||||
from .widgets import SplitDateTimeField
|
||||
|
||||
|
||||
class AgendaAddForm(forms.ModelForm):
|
||||
|
@ -112,10 +112,12 @@ class NewEventForm(forms.ModelForm):
|
|||
model = Event
|
||||
widgets = {
|
||||
'agenda': forms.HiddenInput(),
|
||||
'start_datetime': DateTimeWidget(),
|
||||
'publication_date': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||
}
|
||||
exclude = ['full', 'meeting_type', 'desk', 'slug', 'resources']
|
||||
field_classes = {
|
||||
'start_datetime': SplitDateTimeField,
|
||||
}
|
||||
|
||||
|
||||
class EventForm(forms.ModelForm):
|
||||
|
@ -123,9 +125,11 @@ class EventForm(forms.ModelForm):
|
|||
model = Event
|
||||
widgets = {
|
||||
'agenda': forms.HiddenInput(),
|
||||
'start_datetime': DateTimeWidget(),
|
||||
'publication_date': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
|
||||
}
|
||||
field_classes = {
|
||||
'start_datetime': SplitDateTimeField,
|
||||
}
|
||||
exclude = ['full', 'meeting_type', 'desk', 'resources']
|
||||
|
||||
|
||||
|
@ -255,8 +259,10 @@ class TimePeriodExceptionForm(forms.ModelForm):
|
|||
fields = ['desk', 'start_datetime', 'end_datetime', 'label']
|
||||
widgets = {
|
||||
'desk': forms.HiddenInput(),
|
||||
'start_datetime': DateTimeWidget(),
|
||||
'end_datetime': DateTimeWidget(),
|
||||
}
|
||||
field_classes = {
|
||||
'start_datetime': SplitDateTimeField,
|
||||
'end_datetime': SplitDateTimeField,
|
||||
}
|
||||
|
||||
def clean(self):
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
|
||||
<script>
|
||||
{% if not object.id %}
|
||||
$('[name="start_datetime$date"]').on('change', function() {
|
||||
var $end_datetime = $('[name="end_datetime$date"]');
|
||||
$('[name="start_datetime_0"]').on('change', function() {
|
||||
var $end_datetime = $('[name="end_datetime_0"]');
|
||||
if (! $end_datetime.val()) {
|
||||
var value = $(this).val();
|
||||
if (value && new Date(value).getFullYear() > 999) {
|
||||
|
@ -56,13 +56,13 @@
|
|||
});
|
||||
{% endif %}
|
||||
$('button#allday').on('click', function() {
|
||||
var $start_datetime = $('[name="start_datetime$date"]');
|
||||
var $start_datetime = $('[name="start_datetime_0"]');
|
||||
if ($start_datetime.val()) {
|
||||
var new_date = new Date($start_datetime.val());
|
||||
new_date.setDate(new_date.getDate() + 1);
|
||||
$('[name="start_datetime$time"]').val('00:00');
|
||||
$('[name="end_datetime$date"]').val(new_date.toISOString().substring(0, 10));
|
||||
$('[name="end_datetime$time"]').val('00:00');
|
||||
$('[name="start_datetime_1"]').val('00:00');
|
||||
$('[name="end_datetime_0"]').val(new_date.toISOString().substring(0, 10));
|
||||
$('[name="end_datetime_1"]').val('00:00');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<span class="datetime">
|
||||
{% with widget=widget.subwidgets.0 %}
|
||||
<input type="date" name="{{ widget.name }}"{% if widget.value != None %} value="{{ widget.value }}"{% endif %}{% include "django/forms/widgets/attrs.html" %} />
|
||||
{% endwith %}
|
||||
{% with widget=widget.subwidgets.1 %}
|
||||
<!-- {{ widget.value|pprint }} -->
|
||||
<input type="time" name="{{ widget.name }}" pattern="[0-9]{2}:[0-9]{2}" step="300" {% if widget.value != None %} value="{{ widget.value }}"{% endif %}{% include "django/forms/widgets/attrs.html" %} />
|
||||
{% endwith %}
|
||||
</span>
|
|
@ -1,4 +0,0 @@
|
|||
<span class="datetime">
|
||||
<input type="date" name="{{ widget.name }}$date" {% if widget.value.date != None %} value="{{ widget.value.date }}"{% endif %}{% include "django/forms/widgets/attrs.html" %} />
|
||||
<input type="time" name="{{ widget.name }}$time" pattern="[0-9]{2}:[0-9]{2}" step="300" {% if widget.value.time != None %} value="{{ widget.value.time }}"{% endif %}{% include "django/forms/widgets/attrs.html" %} />
|
||||
</span>
|
|
@ -15,35 +15,21 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import datetime
|
||||
|
||||
from django.forms.widgets import DateTimeInput, TimeInput, SelectMultiple
|
||||
from django.utils import dateparse
|
||||
from django.forms.fields import SplitDateTimeField
|
||||
from django.forms.widgets import TimeInput, SelectMultiple, SplitDateTimeWidget
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
|
||||
class DateTimeWidget(DateTimeInput):
|
||||
template_name = 'chrono/widget_datetime.html'
|
||||
class SplitDateTimeWidget(SplitDateTimeWidget):
|
||||
template_name = 'chrono/splitdatetime.html'
|
||||
|
||||
def format_value(self, value):
|
||||
if value:
|
||||
x = {
|
||||
'date': value.date().strftime('%Y-%m-%d'),
|
||||
'time': value.time().strftime('%H:%M'),
|
||||
}
|
||||
return x
|
||||
return None
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['time_format'] = '%H:%M'
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def value_from_datadict(self, data, files, name):
|
||||
date_string = data.get(name + '$date')
|
||||
time_string = data.get(name + '$time')
|
||||
if not date_string or not time_string:
|
||||
return None
|
||||
date_value = dateparse.parse_date(date_string)
|
||||
time_value = dateparse.parse_time(time_string)
|
||||
if not date_value or not time_value:
|
||||
return None
|
||||
return datetime.datetime.combine(date_value, time_value)
|
||||
|
||||
class SplitDateTimeField(SplitDateTimeField):
|
||||
widget = SplitDateTimeWidget
|
||||
|
||||
|
||||
class TimeWidget(TimeInput):
|
||||
|
|
|
@ -1110,8 +1110,8 @@ def test_add_event(app, admin_user):
|
|||
assert "This agenda doesn't have any event yet." in resp.text
|
||||
year = now().year + 1
|
||||
resp = resp.click('New Event')
|
||||
resp.form['start_datetime$date'] = '%s-02-15' % year
|
||||
resp.form['start_datetime$time'] = '17:00'
|
||||
resp.form['start_datetime_0'] = '%s-02-15' % year
|
||||
resp.form['start_datetime_1'] = '17:00'
|
||||
resp.form['places'] = 10
|
||||
resp = resp.form.submit()
|
||||
resp = resp.follow()
|
||||
|
@ -1130,8 +1130,8 @@ def test_add_event(app, admin_user):
|
|||
# add with a description
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
|
||||
resp = resp.click('New Event')
|
||||
resp.form['start_datetime$date'] = '%s-02-15' % year
|
||||
resp.form['start_datetime$time'] = '18:00'
|
||||
resp.form['start_datetime_0'] = '%s-02-15' % year
|
||||
resp.form['start_datetime_1'] = '18:00'
|
||||
resp.form['publication_date'] = '2020-05-11'
|
||||
resp.form['places'] = 11
|
||||
resp.form['description'] = 'A description'
|
||||
|
@ -1151,11 +1151,15 @@ def test_add_event(app, admin_user):
|
|||
):
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
|
||||
resp = resp.click('New Event')
|
||||
resp.form['start_datetime$date'] = parts[0]
|
||||
resp.form['start_datetime$time'] = parts[1]
|
||||
resp.form['start_datetime_0'] = parts[0]
|
||||
resp.form['start_datetime_1'] = parts[1]
|
||||
resp.form['places'] = 10
|
||||
resp = resp.form.submit()
|
||||
assert resp.text.count('This field is required.') == 1
|
||||
assert (
|
||||
resp.text.count('Enter a valid date')
|
||||
or resp.text.count('Enter a valid time') == 1
|
||||
or resp.text.count('This field is required.') == 1
|
||||
)
|
||||
|
||||
|
||||
def test_add_event_on_missing_agenda(app, admin_user):
|
||||
|
@ -1177,8 +1181,8 @@ def test_add_event_as_manager(app, manager_user):
|
|||
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
|
||||
assert '<h2>Settings' in resp.text
|
||||
resp = resp.click('New Event')
|
||||
resp.form['start_datetime$date'] = '2016-02-15'
|
||||
resp.form['start_datetime$time'] = '17:00'
|
||||
resp.form['start_datetime_0'] = '2016-02-15'
|
||||
resp.form['start_datetime_1'] = '17:00'
|
||||
resp.form['places'] = 10
|
||||
resp = resp.form.submit()
|
||||
resp = resp.follow()
|
||||
|
@ -1192,8 +1196,8 @@ def test_add_event_as_manager(app, manager_user):
|
|||
assert event.end_datetime is None
|
||||
|
||||
resp = resp.click('New Event')
|
||||
resp.form['start_datetime$date'] = '2016-02-15'
|
||||
resp.form['start_datetime$time'] = '17:00'
|
||||
resp.form['start_datetime_0'] = '2016-02-15'
|
||||
resp.form['start_datetime_1'] = '17:00'
|
||||
resp.form['duration'] = 45
|
||||
resp.form['places'] = 12
|
||||
resp = resp.form.submit()
|
||||
|
@ -1213,12 +1217,12 @@ def test_edit_event(app, admin_user):
|
|||
app = login(app)
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
|
||||
resp = resp.click('Feb. 15, 2016, 5 p.m.')
|
||||
assert resp.form['start_datetime$date'].value == '2016-02-15'
|
||||
assert resp.form['start_datetime$time'].value == '17:00'
|
||||
assert resp.form['start_datetime_0'].value == '2016-02-15'
|
||||
assert resp.form['start_datetime_1'].value == '17:00'
|
||||
assert resp.form['publication_date'].value == ''
|
||||
assert resp.form['duration'].value == ''
|
||||
resp.form['start_datetime$date'] = '2016-02-16'
|
||||
resp.form['start_datetime$time'] = '17:00'
|
||||
resp.form['start_datetime_0'] = '2016-02-16'
|
||||
resp.form['start_datetime_1'] = '17:00'
|
||||
resp.form['publication_date'] = '2020-05-11'
|
||||
resp.form['duration'].value = 45
|
||||
resp.form['places'] = 20
|
||||
|
@ -1256,11 +1260,11 @@ def test_edit_event_as_manager(app, manager_user):
|
|||
agenda.save()
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.id, status=200)
|
||||
resp = resp.click('Feb. 15, 2016, 5 p.m.')
|
||||
assert resp.form['start_datetime$date'].value == '2016-02-15'
|
||||
assert resp.form['start_datetime$time'].value == '17:00'
|
||||
assert resp.form['start_datetime_0'].value == '2016-02-15'
|
||||
assert resp.form['start_datetime_1'].value == '17:00'
|
||||
assert resp.form['publication_date'].value == '2020-05-11'
|
||||
resp.form['start_datetime$date'] = '2016-02-16'
|
||||
resp.form['start_datetime$time'] = '17:00'
|
||||
resp.form['start_datetime_0'] = '2016-02-16'
|
||||
resp.form['start_datetime_1'] = '17:00'
|
||||
resp.form['publication_date'] = ''
|
||||
resp.form['places'] = 20
|
||||
resp = resp.form.submit()
|
||||
|
@ -1884,10 +1888,10 @@ def test_meetings_agenda_add_time_period_exception(app, admin_user):
|
|||
tomorrow = make_aware(today + datetime.timedelta(days=1))
|
||||
dt_format = '%Y-%m-%d %H:%M'
|
||||
resp.form['label'] = 'Exception 1'
|
||||
resp.form['start_datetime$date'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime$time'] = '08:00'
|
||||
resp.form['end_datetime$date'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['end_datetime$time'] = '16:00'
|
||||
resp.form['start_datetime_0'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime_1'] = '08:00'
|
||||
resp.form['end_datetime_0'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['end_datetime_1'] = '16:00'
|
||||
resp = resp.form.submit().follow()
|
||||
assert TimePeriodException.objects.count() == 1
|
||||
time_period_exception = TimePeriodException.objects.first()
|
||||
|
@ -1901,10 +1905,10 @@ def test_meetings_agenda_add_time_period_exception(app, admin_user):
|
|||
resp = resp.click('Add a time period exception', index=1)
|
||||
future = tomorrow + datetime.timedelta(days=15)
|
||||
resp.form['label'] = 'Exception 2'
|
||||
resp.form['start_datetime$date'] = future.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime$time'] = '00:00'
|
||||
resp.form['end_datetime$date'] = future.strftime('%Y-%m-%d')
|
||||
resp.form['end_datetime$time'] = '16:00'
|
||||
resp.form['start_datetime_0'] = future.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime_1'] = '00:00'
|
||||
resp.form['end_datetime_0'] = future.strftime('%Y-%m-%d')
|
||||
resp.form['end_datetime_1'] = '16:00'
|
||||
resp = resp.form.submit().follow()
|
||||
assert TimePeriodException.objects.count() == 2
|
||||
assert 'Exception 1' in resp.text
|
||||
|
@ -1932,10 +1936,10 @@ def test_meetings_agenda_add_time_period_exception_when_booking_exists(app, admi
|
|||
# fields should be marked with errors
|
||||
assert resp.text.count('This field is required.') == 2
|
||||
# try again with data in fields
|
||||
resp.form['start_datetime$date'] = '2017-05-22'
|
||||
resp.form['start_datetime$time'] = '08:00'
|
||||
resp.form['end_datetime$date'] = '2017-05-26'
|
||||
resp.form['end_datetime$time'] = '17:30'
|
||||
resp.form['start_datetime_0'] = '2017-05-22'
|
||||
resp.form['start_datetime_1'] = '08:00'
|
||||
resp.form['end_datetime_0'] = '2017-05-26'
|
||||
resp.form['end_datetime_1'] = '17:30'
|
||||
resp = resp.form.submit().follow()
|
||||
assert 'Exception added. Note: one or several bookings exists within this time slot.' in resp.text
|
||||
assert TimePeriodException.objects.count() == 1
|
||||
|
@ -1957,10 +1961,10 @@ def test_meetings_agenda_add_time_period_exception_when_cancelled_booking_exists
|
|||
login(app)
|
||||
resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
|
||||
resp = resp.click('Add a time period exception')
|
||||
resp.form['start_datetime$date'] = '2017-05-22'
|
||||
resp.form['start_datetime$time'] = '08:00'
|
||||
resp.form['end_datetime$date'] = '2017-05-26'
|
||||
resp.form['end_datetime$time'] = '17:30'
|
||||
resp.form['start_datetime_0'] = '2017-05-22'
|
||||
resp.form['start_datetime_1'] = '08:00'
|
||||
resp.form['end_datetime_0'] = '2017-05-26'
|
||||
resp.form['end_datetime_1'] = '17:30'
|
||||
resp = resp.form.submit().follow()
|
||||
assert 'Exception added. Note: one or several bookings exists within this time slot.' not in resp.text
|
||||
assert TimePeriodException.objects.count() == 1
|
||||
|
@ -1969,10 +1973,10 @@ def test_meetings_agenda_add_time_period_exception_when_cancelled_booking_exists
|
|||
def test_meetings_agenda_add_invalid_time_period_exception():
|
||||
form = TimePeriodExceptionForm(
|
||||
data={
|
||||
'start_datetime$date': '2017-05-26',
|
||||
'start_datetime$time': '17:30',
|
||||
'end_datetime$date': '2017-05-22',
|
||||
'end_datetime$time': '08:00',
|
||||
'start_datetime_0': '2017-05-26',
|
||||
'start_datetime_1': '17:30',
|
||||
'end_datetime_0': '2017-05-22',
|
||||
'end_datetime_1': '08:00',
|
||||
}
|
||||
)
|
||||
assert form.is_valid() is False
|
||||
|
@ -1981,10 +1985,10 @@ def test_meetings_agenda_add_invalid_time_period_exception():
|
|||
# start_datetime is invalid
|
||||
form = TimePeriodExceptionForm(
|
||||
data={
|
||||
'start_datetime$date': '2017-05-26',
|
||||
'start_datetime$time': 'foo',
|
||||
'end_datetime$date': '2017-05-22',
|
||||
'end_datetime$time': '08:00',
|
||||
'start_datetime_0': '2017-05-26',
|
||||
'start_datetime_1': 'foo',
|
||||
'end_datetime_0': '2017-05-22',
|
||||
'end_datetime_1': '08:00',
|
||||
}
|
||||
)
|
||||
assert form.is_valid() is False
|
||||
|
@ -1992,10 +1996,10 @@ def test_meetings_agenda_add_invalid_time_period_exception():
|
|||
# end_datetime is invalid
|
||||
form = TimePeriodExceptionForm(
|
||||
data={
|
||||
'start_datetime$date': '2017-05-26',
|
||||
'start_datetime$time': '17:30',
|
||||
'end_datetime$date': 'bar',
|
||||
'end_datetime$time': '08:00',
|
||||
'start_datetime_0': '2017-05-26',
|
||||
'start_datetime_1': '17:30',
|
||||
'end_datetime_0': 'bar',
|
||||
'end_datetime_1': '08:00',
|
||||
}
|
||||
)
|
||||
assert form.is_valid() is False
|
||||
|
@ -2015,10 +2019,10 @@ def test_meetings_agenda_delete_time_period_exception(app, admin_user):
|
|||
tomorrow = make_aware(today + datetime.timedelta(days=15))
|
||||
dt_format = '%Y-%m-%d %H:%M'
|
||||
resp.form['label'] = 'Exception 1'
|
||||
resp.form['start_datetime$date'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime$time'] = '08:00'
|
||||
resp.form['end_datetime$date'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['end_datetime$time'] = '16:00'
|
||||
resp.form['start_datetime_0'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime_1'] = '08:00'
|
||||
resp.form['end_datetime_0'] = tomorrow.strftime('%Y-%m-%d')
|
||||
resp.form['end_datetime_1'] = '16:00'
|
||||
resp = resp.form.submit().follow()
|
||||
assert TimePeriodException.objects.count() == 1
|
||||
time_period_exception = TimePeriodException.objects.first()
|
||||
|
@ -3099,8 +3103,8 @@ def test_agenda_view_edit_event(app, manager_user):
|
|||
resp = app.get(event_url)
|
||||
assert 'Options' in resp.text
|
||||
resp = resp.click('Options')
|
||||
resp.form['start_datetime$date'] = agenda.event_set.first().start_datetime.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime$time'] = agenda.event_set.first().start_datetime.strftime('%H:%M')
|
||||
resp.form['start_datetime_0'] = agenda.event_set.first().start_datetime.strftime('%Y-%m-%d')
|
||||
resp.form['start_datetime_1'] = agenda.event_set.first().start_datetime.strftime('%H:%M')
|
||||
resp = resp.form.submit(status=302).follow()
|
||||
assert event_url == resp.request.url
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ from django.utils.timezone import now
|
|||
|
||||
import pytest
|
||||
|
||||
from chrono.manager.widgets import DateTimeWidget, TimeWidget
|
||||
from chrono.agendas.models import Agenda
|
||||
from chrono.agendas.models import Booking
|
||||
from chrono.agendas.models import Desk
|
||||
|
@ -19,11 +18,6 @@ from chrono.agendas.models import MeetingType
|
|||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_widgets_init():
|
||||
DateTimeWidget()
|
||||
TimeWidget()
|
||||
|
||||
|
||||
def check_ignore_reason(event, value):
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("SELECT _ignore_reason FROM agendas_event WHERE id = %s", [event.pk])
|
||||
|
|
Loading…
Reference in New Issue