Skip to content

Commit 008dc1e

Browse files
authored
Merge pull request #62 from arbisoft/develop
✨ Release 0.1.0
2 parents 223ff23 + c6aecf1 commit 008dc1e

File tree

18 files changed

+419
-41
lines changed

18 files changed

+419
-41
lines changed

arbisoft_sessions_portal/settings/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
'django.contrib.contenttypes',
5959
'django.contrib.sessions',
6060
'django.contrib.messages',
61+
'django.contrib.postgres',
6162
'django.contrib.staticfiles',
6263
'rest_framework',
6364
'django_filters',

events/admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ class EventAdmin(admin.ModelAdmin):
5252

5353
fieldsets = (
5454
(None, {
55-
'fields': ('creator', 'title', 'description', 'event_time',
55+
'fields': ('creator', 'title', 'slug', 'description', 'event_time',
5656
'event_type', 'status', 'is_featured',
57-
'tags', 'playlists', 'videoasset')
57+
'tags', 'playlists', 'videoasset',)
5858
}),
5959
)
6060

events/apps.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ class EventsConfig(AppConfig):
55
""" Configuration for the events app """
66
default_auto_field = 'django.db.models.BigAutoField'
77
name = 'events'
8+
9+
def ready(self):
10+
import events.signals # pylint: disable=import-outside-toplevel, unused-import

events/factories.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from django.contrib.auth import get_user_model
55
from django.utils import timezone
66

7-
from events.models import Event, Playlist, Tag, VideoAsset
7+
from events.models import Event, EventPresenter, Playlist, Tag, VideoAsset
88

99
fake = Faker()
1010
User = get_user_model()
@@ -61,3 +61,13 @@ class Meta:
6161
status = VideoAsset.VideoStatus.READY
6262
duration = factory.Faker("random_int", min=60, max=3600) # Duration in seconds
6363
file_size = factory.Faker("random_int", min=1024, max=10485760) # File size in bytes
64+
65+
66+
class EventPresenterFactory(factory.django.DjangoModelFactory):
67+
"""Factory for EventPresenter model"""
68+
69+
class Meta:
70+
model = EventPresenter
71+
72+
event = factory.SubFactory(EventFactory)
73+
user = factory.SubFactory(UserFactory)

events/forms.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,16 @@ class Meta:
5353

5454
def __init__(self, *args, **kwargs):
5555
super().__init__(*args, **kwargs)
56-
5756
current_event = self.instance
57+
58+
# Disable slug field if the instance is new
59+
if current_event and current_event.pk:
60+
self.fields['slug'].disabled = False
61+
else:
62+
self.fields['slug'].disabled = True
63+
64+
# Populate videoasset queryset based on the current event
65+
# If the event is new, show all video assets without an event
5866
qs = VideoAsset.objects.filter(event__isnull=True)
5967

6068
if current_event.pk:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.2.16 on 2025-06-10 01:47
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('events', '0008_alter_event_tags'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='event',
15+
name='slug',
16+
field=models.SlugField(blank=True, max_length=255, null=True),
17+
),
18+
]
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Generated by Django 4.2.16 on 2025-06-10 02:02
2+
3+
from django.db import migrations
4+
from django.utils.text import slugify
5+
6+
def populate_event_slugs(apps, schema_editor):
7+
Event = apps.get_model('events', 'Event')
8+
9+
titles_seen = {}
10+
11+
for event in Event.objects.all().order_by('id'):
12+
if not event.slug:
13+
base_slug = slugify(event.title)
14+
15+
if base_slug in titles_seen:
16+
event.slug = f"{base_slug}-{event.id}"
17+
else:
18+
if Event.objects.filter(title=event.title).exclude(pk=event.pk).exists():
19+
event.slug = f"{base_slug}-{event.id}"
20+
else:
21+
event.slug = base_slug
22+
23+
titles_seen[base_slug] = event.id
24+
25+
event.save(update_fields=['slug'])
26+
27+
class Migration(migrations.Migration):
28+
29+
dependencies = [
30+
('events', '0009_event_slug'),
31+
]
32+
33+
operations = [
34+
migrations.RunPython(populate_event_slugs, reverse_code=migrations.RunPython.noop),
35+
]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Generated by Django 4.2.21 on 2025-06-14 03:23
2+
3+
from django.contrib.postgres.operations import CreateExtension
4+
from django.db import migrations
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('events', '0010_populate_event_slugs'),
11+
]
12+
13+
operations = [
14+
CreateExtension('pg_trgm'),
15+
]

events/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class EventStatus(models.TextChoices):
5959

6060
creator = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name='events')
6161
title = models.CharField(max_length=255)
62+
slug = models.SlugField(max_length=255, blank=True, null=True)
6263
description = models.TextField()
6364
event_time = models.DateTimeField()
6465
event_type = models.CharField(max_length=20, choices=EventType.choices, default=EventType.SESSION)

events/signals.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from django.db.models.signals import post_save
2+
from django.dispatch import receiver
3+
from django.utils.text import slugify
4+
5+
from events.models import Event
6+
7+
8+
@receiver(post_save, sender=Event)
9+
def set_slug_on_create(sender, instance, created, **kwargs): # pylint: disable=unused-argument
10+
"""
11+
Set a slug for the event instance if it is created and does not have a slug.
12+
The slug is generated from the title and includes the event ID to ensure uniqueness.
13+
"""
14+
if created and not instance.slug:
15+
base_slug = slugify(instance.title)
16+
exists_with_title = Event.objects.filter(title=instance.title).exclude(pk=instance.pk).exists()
17+
18+
if exists_with_title:
19+
slug = f"{base_slug}-{instance.id}"
20+
else:
21+
slug = base_slug
22+
23+
instance.slug = slug
24+
instance.save(update_fields=['slug'])

0 commit comments

Comments
 (0)