From 0bea0173ba04ec0a4a1c12171e60b90bddd38a20 Mon Sep 17 00:00:00 2001 From: Kresten Laust Date: Fri, 18 Aug 2023 13:43:16 +0200 Subject: [PATCH 1/5] Added start_datetime and end_datetime fields to KioskItem, and added conditions for filtering. --- kiosk/admin.py | 4 ++-- kiosk/models.py | 6 ++++++ kiosk/views.py | 14 ++++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/kiosk/admin.py b/kiosk/admin.py index d7cf027b..c56dd9bc 100644 --- a/kiosk/admin.py +++ b/kiosk/admin.py @@ -19,9 +19,9 @@ def set_inactive_kiosk_item(modeladmin, request, queryset): class KioskItemAdmin(admin.ModelAdmin): search_fields = ('name',) - list_display = ('active', 'name', 'notes', 'ordering', 'uploaded_date') + list_display = ('active', 'name', 'notes', 'ordering', 'uploaded_date', 'start_datetime', 'end_datetime') list_filter = ('active',) - list_display_links = ('active', 'name', 'notes', 'ordering', 'uploaded_date') + list_display_links = ('active', 'name', 'notes', 'ordering', 'uploaded_date', 'start_datetime', 'end_datetime') actions = [set_active_kiosk_item, set_inactive_kiosk_item] diff --git a/kiosk/models.py b/kiosk/models.py index 420e9136..88f0485c 100644 --- a/kiosk/models.py +++ b/kiosk/models.py @@ -1,4 +1,5 @@ import random +from django.utils import timezone from .validators import validate_file_extension, valid_images from django.db import models import os @@ -15,8 +16,13 @@ class KioskItem(models.Model): active = models.BooleanField(default=True) media = models.FileField(upload_to='kiosk', null=False, validators=[validate_file_extension]) ordering = models.IntegerField(null=False, default=random_ordering, blank=False) + start_datetime = models.DateTimeField(default=timezone.now(), blank=True) + end_datetime = models.DateTimeField(null=True, blank=True) @property def is_image(self): name, extension = os.path.splitext(self.media.name) return extension in valid_images + + def is_active_period(self, current_time) -> bool: + return (self.start_datetime < current_time) and (self.end_datetime is None or self.end_datetime > current_time) diff --git a/kiosk/views.py b/kiosk/views.py index 664391bc..2b87d6f0 100644 --- a/kiosk/views.py +++ b/kiosk/views.py @@ -1,5 +1,7 @@ import json +from datetime import datetime +from django.utils import timezone from django.db.models import Q from django.http import Http404, HttpResponse from django.shortcuts import render @@ -15,7 +17,8 @@ def find_random_media(request): """ Randomly get a media and return the relative url """ - item = KioskItem.objects.filter(active=True).order_by('?').first() + item = KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now())\ + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())).order_by('?').first() if item is None: raise Http404("No active kiosk items found") @@ -30,19 +33,22 @@ def find_random_media(request): def find_next_media_real(request, item_id): item = KioskItem.objects.get(pk=item_id) - item_count = KioskItem.objects.filter(active=True).count() + item_count = KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now())\ + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())).count() if item_count == 0: raise Http404("No active kiosk items found") # Get the item at the index, trust that Django does this smartly. try: next_item = ( - KioskItem.objects.filter(active=True) + KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) .order_by('ordering', 'id') .filter(Q(ordering__gt=item.ordering) | (Q(ordering=item.ordering) & Q(id__gt=item.id)))[0] ) except IndexError: - next_item = KioskItem.objects.filter(active=True).order_by('ordering', 'id')[0] + next_item = KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now())\ + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())).order_by('ordering', 'id')[0] response_data = { "id": next_item.id, "url": next_item.media.url, From ef03438e966dc18ea47e7c031c98d54659feae5f Mon Sep 17 00:00:00 2001 From: Kresten Laust Date: Fri, 18 Aug 2023 14:26:56 +0200 Subject: [PATCH 2/5] Formatted code using black --- kiosk/views.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/kiosk/views.py b/kiosk/views.py index 2b87d6f0..2472c8fc 100644 --- a/kiosk/views.py +++ b/kiosk/views.py @@ -17,8 +17,12 @@ def find_random_media(request): """ Randomly get a media and return the relative url """ - item = KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now())\ - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())).order_by('?').first() + item = ( + KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + .order_by('?') + .first() + ) if item is None: raise Http404("No active kiosk items found") @@ -33,8 +37,11 @@ def find_random_media(request): def find_next_media_real(request, item_id): item = KioskItem.objects.get(pk=item_id) - item_count = KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now())\ - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())).count() + item_count = ( + KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + .count() + ) if item_count == 0: raise Http404("No active kiosk items found") @@ -47,8 +54,11 @@ def find_next_media_real(request, item_id): .filter(Q(ordering__gt=item.ordering) | (Q(ordering=item.ordering) & Q(id__gt=item.id)))[0] ) except IndexError: - next_item = KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now())\ - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())).order_by('ordering', 'id')[0] + next_item = ( + KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) + .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + .order_by('ordering', 'id')[0] + ) response_data = { "id": next_item.id, "url": next_item.media.url, From 83fc43274e286e99497a3a0a1a1eeb34e6eec018 Mon Sep 17 00:00:00 2001 From: Kresten Laust Date: Fri, 18 Aug 2023 14:33:23 +0200 Subject: [PATCH 3/5] Updated migration --- kiosk/migrations/0007_auto_20230818_1431.py | 25 +++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 kiosk/migrations/0007_auto_20230818_1431.py diff --git a/kiosk/migrations/0007_auto_20230818_1431.py b/kiosk/migrations/0007_auto_20230818_1431.py new file mode 100644 index 00000000..b149013e --- /dev/null +++ b/kiosk/migrations/0007_auto_20230818_1431.py @@ -0,0 +1,25 @@ +# Generated by Django 2.2.28 on 2023-08-18 12:31 + +import datetime +from django.db import migrations, models +from django.utils.timezone import utc + + +class Migration(migrations.Migration): + + dependencies = [ + ('kiosk', '0006_remove_image_20201112_1715'), + ] + + operations = [ + migrations.AddField( + model_name='kioskitem', + name='end_datetime', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='kioskitem', + name='start_datetime', + field=models.DateTimeField(blank=True, default=datetime.datetime(2023, 8, 18, 12, 31, 12, 792200, tzinfo=utc)), + ), + ] From eca1306106f9ce995e3502eadcaef5022d69699e Mon Sep 17 00:00:00 2001 From: Kresten Laust Date: Wed, 23 Aug 2023 11:41:18 +0200 Subject: [PATCH 4/5] Removed default value for start date, made null represent current time. --- ...818_1431.py => 0007_auto_20230823_1138.py} | 6 ++-- kiosk/models.py | 5 +--- kiosk/views.py | 28 +++++++++++++------ 3 files changed, 23 insertions(+), 16 deletions(-) rename kiosk/migrations/{0007_auto_20230818_1431.py => 0007_auto_20230823_1138.py} (67%) diff --git a/kiosk/migrations/0007_auto_20230818_1431.py b/kiosk/migrations/0007_auto_20230823_1138.py similarity index 67% rename from kiosk/migrations/0007_auto_20230818_1431.py rename to kiosk/migrations/0007_auto_20230823_1138.py index b149013e..84b15a3b 100644 --- a/kiosk/migrations/0007_auto_20230818_1431.py +++ b/kiosk/migrations/0007_auto_20230823_1138.py @@ -1,8 +1,6 @@ -# Generated by Django 2.2.28 on 2023-08-18 12:31 +# Generated by Django 2.2.28 on 2023-08-23 09:38 -import datetime from django.db import migrations, models -from django.utils.timezone import utc class Migration(migrations.Migration): @@ -20,6 +18,6 @@ class Migration(migrations.Migration): migrations.AddField( model_name='kioskitem', name='start_datetime', - field=models.DateTimeField(blank=True, default=datetime.datetime(2023, 8, 18, 12, 31, 12, 792200, tzinfo=utc)), + field=models.DateTimeField(blank=True, null=True), ), ] diff --git a/kiosk/models.py b/kiosk/models.py index 88f0485c..7499d7f8 100644 --- a/kiosk/models.py +++ b/kiosk/models.py @@ -16,13 +16,10 @@ class KioskItem(models.Model): active = models.BooleanField(default=True) media = models.FileField(upload_to='kiosk', null=False, validators=[validate_file_extension]) ordering = models.IntegerField(null=False, default=random_ordering, blank=False) - start_datetime = models.DateTimeField(default=timezone.now(), blank=True) + start_datetime = models.DateTimeField(null=True, blank=True) end_datetime = models.DateTimeField(null=True, blank=True) @property def is_image(self): name, extension = os.path.splitext(self.media.name) return extension in valid_images - - def is_active_period(self, current_time) -> bool: - return (self.start_datetime < current_time) and (self.end_datetime is None or self.end_datetime > current_time) diff --git a/kiosk/views.py b/kiosk/views.py index 2472c8fc..3ee3d931 100644 --- a/kiosk/views.py +++ b/kiosk/views.py @@ -18,8 +18,11 @@ def find_random_media(request): Randomly get a media and return the relative url """ item = ( - KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + KioskItem.objects.filter(active=True) + .filter( + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & + (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + ) .order_by('?') .first() ) @@ -38,8 +41,11 @@ def find_next_media_real(request, item_id): item = KioskItem.objects.get(pk=item_id) item_count = ( - KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + KioskItem.objects.filter(active=True) + .filter( + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & + (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + ) .count() ) if item_count == 0: @@ -48,15 +54,21 @@ def find_next_media_real(request, item_id): # Get the item at the index, trust that Django does this smartly. try: next_item = ( - KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + KioskItem.objects.filter(active=True) + .filter( + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & + (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + ) .order_by('ordering', 'id') .filter(Q(ordering__gt=item.ordering) | (Q(ordering=item.ordering) & Q(id__gt=item.id)))[0] ) except IndexError: next_item = ( - KioskItem.objects.filter(active=True, start_datetime__lte=timezone.now()) - .filter(Q(end_datetime__isnull=True) | Q(end_datetime__gt=timezone.now())) + KioskItem.objects.filter(active=True) + .filter( + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & + (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + ) .order_by('ordering', 'id')[0] ) response_data = { From 006b926c17f10bb0ea23d376a81f7f5e3f27d318 Mon Sep 17 00:00:00 2001 From: falkecarlsen <11318702+falkecarlsen@users.noreply.github.com> Date: Sun, 3 Sep 2023 10:36:34 +0200 Subject: [PATCH 5/5] fix black --- kiosk/views.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/kiosk/views.py b/kiosk/views.py index 3ee3d931..793ab82e 100644 --- a/kiosk/views.py +++ b/kiosk/views.py @@ -20,8 +20,8 @@ def find_random_media(request): item = ( KioskItem.objects.filter(active=True) .filter( - (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & - (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) + & (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) ) .order_by('?') .first() @@ -43,8 +43,8 @@ def find_next_media_real(request, item_id): item_count = ( KioskItem.objects.filter(active=True) .filter( - (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & - (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) + & (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) ) .count() ) @@ -56,8 +56,8 @@ def find_next_media_real(request, item_id): next_item = ( KioskItem.objects.filter(active=True) .filter( - (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & - (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) + & (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) ) .order_by('ordering', 'id') .filter(Q(ordering__gt=item.ordering) | (Q(ordering=item.ordering) & Q(id__gt=item.id)))[0] @@ -66,8 +66,8 @@ def find_next_media_real(request, item_id): next_item = ( KioskItem.objects.filter(active=True) .filter( - (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) & - (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) + (Q(start_datetime__isnull=True) | Q(start_datetime__lte=timezone.now())) + & (Q(end_datetime__isnull=True) | Q(end_datetime__gte=timezone.now())) ) .order_by('ordering', 'id')[0] )