0001-agendas-allow-custom-event-api-text-53661.patch
chrono/agendas/migrations/0088_agenda_event_display_template.py | ||
---|---|---|
1 |
# Generated by Django 2.2.19 on 2021-05-19 12:23 |
|
2 | ||
3 |
from django.db import migrations, models |
|
4 | ||
5 | ||
6 |
class Migration(migrations.Migration): |
|
7 | ||
8 |
dependencies = [ |
|
9 |
('agendas', '0087_booking_user_name'), |
|
10 |
] |
|
11 | ||
12 |
operations = [ |
|
13 |
migrations.AddField( |
|
14 |
model_name='agenda', |
|
15 |
name='event_display_template', |
|
16 |
field=models.CharField( |
|
17 |
blank=True, |
|
18 |
help_text='By default event labels will be displayed to users. This allows for a custom template to include additional informations. For example, "{{ event.label }} - {{ event.start_datetime }}" will show event datetime after label.', |
|
19 |
max_length=256, |
|
20 |
verbose_name='Event display template', |
|
21 |
), |
|
22 |
), |
|
23 |
] |
chrono/agendas/models.py | ||
---|---|---|
211 | 211 |
blank=True, |
212 | 212 |
validators=[django_template_validator], |
213 | 213 |
) |
214 |
event_display_template = models.CharField( |
|
215 |
_('Event display template'), |
|
216 |
max_length=256, |
|
217 |
blank=True, |
|
218 |
help_text=_( |
|
219 |
'By default event labels will be displayed to users. This allows for a custom template to include additional informations. For example, "{{ event.label }} - {{ event.start_datetime }}" will show event datetime after label.' |
|
220 |
), |
|
221 |
) |
|
214 | 222 | |
215 | 223 |
class Meta: |
216 | 224 |
ordering = ['label'] |
chrono/api/views.py | ||
---|---|---|
23 | 23 |
from django.db.models import Prefetch, Q |
24 | 24 |
from django.http import Http404, HttpResponse |
25 | 25 |
from django.shortcuts import get_object_or_404 |
26 |
from django.template import Context, Template |
|
26 | 27 |
from django.urls import reverse |
27 | 28 |
from django.utils.dateparse import parse_date, parse_datetime |
28 | 29 |
from django.utils.encoding import force_text |
... | ... | |
414 | 415 |
def get_event_detail(request, event, agenda=None, min_places=1): |
415 | 416 |
agenda = agenda or event.agenda |
416 | 417 |
event_text = force_text(event) |
417 |
if event.label and event.primary_event is not None: |
|
418 |
if agenda.event_display_template: |
|
419 |
event_text = Template(agenda.event_display_template).render(Context({'event': event})) |
|
420 |
elif event.label and event.primary_event is not None: |
|
418 | 421 |
event_text = '%s (%s)' % ( |
419 | 422 |
event.label, |
420 | 423 |
date_format(localtime(event.start_datetime), 'DATETIME_FORMAT'), |
chrono/manager/forms.py | ||
---|---|---|
101 | 101 |
'anonymize_delay', |
102 | 102 |
'default_view', |
103 | 103 |
'booking_form_url', |
104 |
'event_display_template', |
|
104 | 105 |
] |
105 | 106 | |
106 | 107 |
def __init__(self, *args, **kwargs): |
107 | 108 |
super(AgendaEditForm, self).__init__(*args, **kwargs) |
108 | 109 |
if kwargs['instance'].kind != 'events': |
109 | 110 |
del self.fields['booking_form_url'] |
111 |
del self.fields['event_display_template'] |
|
110 | 112 |
self.fields['default_view'].choices = [ |
111 | 113 |
(k, v) for k, v in self.fields['default_view'].choices if k != 'open_events' |
112 | 114 |
] |
tests/manager/test_all.py | ||
---|---|---|
469 | 469 |
assert resp.context['form'].initial['default_view'] == 'month' |
470 | 470 |
assert 'open_events' in [k for k, v in resp.context['form'].fields['default_view'].choices] |
471 | 471 |
assert 'booking_form_url' in resp.context['form'].fields |
472 |
assert 'event_display_template' in resp.context['form'].fields |
|
472 | 473 |
resp = resp.form.submit() |
473 | 474 |
assert resp.location.endswith('/manage/agendas/%s/settings' % agenda_events.pk) |
474 | 475 |
resp = resp.follow() |
... | ... | |
482 | 483 |
assert 'default_view' in resp.context['form'].fields |
483 | 484 |
assert 'open_events' not in [k for k, v in resp.context['form'].fields['default_view'].choices] |
484 | 485 |
assert 'booking_form_url' not in resp.context['form'].fields |
486 |
assert 'event_display_template' not in resp.context['form'].fields |
|
485 | 487 | |
486 | 488 |
resp.form['default_view'] = 'month' |
487 | 489 |
resp.form.submit() |
... | ... | |
492 | 494 |
assert resp.form['default_view'].value == 'month' |
493 | 495 |
assert 'default_view' in resp.context['form'].fields |
494 | 496 |
assert 'booking_form_url' not in resp.context['form'].fields |
497 |
assert 'event_display_template' not in resp.context['form'].fields |
|
495 | 498 |
assert 'open_events' not in [k for k, v in resp.context['form'].fields['default_view'].choices] |
496 | 499 | |
497 | 500 |
tests/test_api.py | ||
---|---|---|
540 | 540 |
assert 'data' in resp.json |
541 | 541 | |
542 | 542 | |
543 |
@pytest.mark.freeze_time('2021-05-06 14:00') |
|
543 | 544 |
def test_datetime_api_label(app): |
544 | 545 |
agenda = Agenda.objects.create(label='Foo bar', kind='events', minimal_booking_delay=0) |
545 |
Event.objects.create( |
|
546 |
event = Event.objects.create(
|
|
546 | 547 |
label='Hello world', |
547 | 548 |
slug='event-slug', |
548 | 549 |
start_datetime=(now() + datetime.timedelta(days=1)), |
... | ... | |
550 | 551 |
agenda=agenda, |
551 | 552 |
) |
552 | 553 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
553 |
assert 'Hello world' in [x['text'] for x in resp.json['data']] |
|
554 |
assert 'Hello world' == resp.json['data'][0]['text'] |
|
555 | ||
556 |
agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}' |
|
557 |
agenda.save() |
|
558 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
|
559 |
assert resp.json['data'][0]['text'] == 'Hello world - May 7, 2021, 4 p.m.' |
|
560 | ||
561 |
Booking.objects.create(event=event) |
|
562 |
agenda.event_display_template = ( |
|
563 |
'{{ event.label }} ({{ event.remaining_places }}/{{ event.places }} places remaining)' |
|
564 |
) |
|
565 |
agenda.save() |
|
566 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
|
567 |
assert resp.json['data'][0]['text'] == 'Hello world (4/5 places remaining)' |
|
554 | 568 | |
555 | 569 | |
556 | 570 |
def test_datetime_api_urls(app): |
... | ... | |
6338 | 6352 |
assert len(resp.json['data']) == 2 |
6339 | 6353 |
assert resp.json['data'][0]['id'] == 'abc:2021-02-02-1305' |
6340 | 6354 | |
6355 |
# events follow agenda display template |
|
6356 |
agenda.event_display_template = '{{ event.label }} - {{ event.start_datetime }}' |
|
6357 |
agenda.save() |
|
6358 |
resp = app.get('/api/agenda/%s/datetimes/' % agenda.slug) |
|
6359 |
assert resp.json['data'][0]['text'] == 'Test - Feb. 2, 2021, 1:05 p.m.' |
|
6360 | ||
6341 | 6361 | |
6342 | 6362 |
def test_recurring_events_api_various_times(app, user, mock_now): |
6343 | 6363 |
agenda = Agenda.objects.create( |
6344 |
- |