Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added auths/management/__init__.py
Empty file.
Empty file.
19 changes: 19 additions & 0 deletions auths/management/commands/make_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand

from root.env_config import env


class Command(BaseCommand):
help = "Create an admin user if it does not exist"

def handle(self, *args, **kwargs):
admin_username = env("DJANGO_ADMIN_USERNAME")
admin_password = env("DJANGO_ADMIN_PASSWORD")
admin_email = env("DJANGO_ADMIN_EMAIL")

if not User.objects.filter(username=admin_username).exists():
User.objects.create_superuser(admin_username, admin_email, admin_password)
self.stdout.write(self.style.SUCCESS(f'Admin user "{admin_username}" created'))
else:
self.stdout.write(self.style.WARNING(f'Admin user "{admin_username}" already exists'))
5 changes: 5 additions & 0 deletions env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Django Superuser details
DJANGO_ADMIN_USERNAME="admin"
DJANGO_ADMIN_EMAIL="admin@admin.com"
DJANGO_ADMIN_PASSWORD="admin"

# WARNING: Set to False in production to enable security features
DJANGO_DEBUG=False

Expand Down
103 changes: 88 additions & 15 deletions events/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
from django.contrib import admin
from django.db.models import Q

from root.base_admin import SummernoteModelAdmin # type: ignore

from .enums import EventStatus
from .models import Banner, Event, EventSignup, Location, Schedule
from events.enums import EventStatus
from events.filters.category import ActiveCategoryFilter
from events.models.banner import Banner
from events.models.category import Category
from events.models.event import Event
from events.models.location import Location
from events.models.schedule import Schedule
from events.models.signup import EventSignup
from root.base_admin import SummernoteModelAdmin


class LocationInline(admin.StackedInline):
Expand All @@ -29,12 +34,22 @@ class ScheduleInline(admin.StackedInline):
class EventAdmin(SummernoteModelAdmin, admin.ModelAdmin):
list_display = (
"title",
"category",
"total_participants",
"formatted_created_at",
"status",
)
search_fields = ("title", "description", "location")
list_filter = ("created_at", "updated_at", "status")
search_fields = (
"title",
"description",
"status",
"category__name",
)
list_filter = (
"created_at",
"status",
ActiveCategoryFilter,
)
readonly_fields = ["created_by"]
inlines = [LocationInline, ScheduleInline, BannerInline]

Expand All @@ -60,8 +75,16 @@ def get_queryset(self, request):

@admin.register(EventSignup)
class EventSignupAdmin(admin.ModelAdmin):
list_display = ("user", "event", "signup_date")
search_fields = ("user", "event", "signup_date")
list_display = (
"user",
"event",
"signup_date",
)
search_fields = (
"user",
"event",
"signup_date",
)
list_filter = (
"event",
"signup_date",
Expand All @@ -71,20 +94,70 @@ class EventSignupAdmin(admin.ModelAdmin):

@admin.register(Location)
class LocationAdmin(admin.ModelAdmin):
list_display = ("address", "google_map_link")
search_fields = ("address", "google_map_link")
list_display = (
"address",
"google_map_link",
)
search_fields = (
"address",
"google_map_link",
)
list_filter = ("address",)


@admin.register(Banner)
class BannerAdmin(admin.ModelAdmin):
list_display = ("event", "image")
search_fields = ("event", "image")
list_display = (
"event",
"image",
)
search_fields = (
"event",
"image",
)
list_filter = ("event",)


@admin.register(Schedule)
class ScheduleAdmin(admin.ModelAdmin):
list_display = ("event", "start_date", "start_time", "end_date", "end_time")
search_fields = ("event", "start_date", "start_time", "end_date", "end_time")
list_filter = ("event", "start_date", "start_time", "end_date", "end_time")
list_display = (
"event",
"start_date",
"start_time",
"end_date",
"end_time",
)
search_fields = (
"event",
"start_date",
"start_time",
"end_date",
"end_time",
)
list_filter = (
"event",
"start_date",
"start_time",
"end_date",
"end_time",
)


@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = (
"name",
"created_at",
"is_active",
)
search_fields = (
"name",
"is_active",
)
list_filter = (
"name",
"is_active",
)
readonly_fields = [
"created_at",
]
Empty file added events/filters/__init__.py
Empty file.
17 changes: 17 additions & 0 deletions events/filters/category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.contrib.admin import SimpleListFilter

from events.models.category import Category


class ActiveCategoryFilter(SimpleListFilter):
title = "Active Category"
parameter_name = "category"

def lookups(self, request, model_admin): # noqa: PLR6301
active_categories = Category.objects.filter(is_active=True).order_by("name")
return [(category.id, category.name) for category in active_categories]

def queryset(self, request, queryset):
if self.value():
return queryset.filter(category__id=self.value())
return queryset
Empty file added events/management/__init__.py
Empty file.
Empty file.
42 changes: 29 additions & 13 deletions events/management/commands/fake_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
from PIL import Image

from events.enums import EventStatus
from events.models import Banner, Event, Location, Schedule
from events.models.banner import Banner
from events.models.category import Category
from events.models.event import Event
from events.models.location import Location
from events.models.schedule import Schedule

fake = Faker()

Expand All @@ -21,12 +25,15 @@ def handle(self, *args, **kwargs):
username="fakeuser", defaults={"password": "fakepassword"}
)

for _ in range(4):
self.create_category()

for _ in range(10):
description_html = "".join(fake.paragraphs(nb=3, ext_word_list=None))

event = Event.objects.create(
title=fake.sentence(nb_words=6),
description=f"<p>{description_html}</p>",
category=Category.objects.filter(is_active=True).order_by("?").first(),
total_participants=fake.random_int(min=10, max=100),
created_by=user,
status=EventStatus.DRAFT,
Expand All @@ -41,6 +48,16 @@ def handle(self, *args, **kwargs):

self.stdout.write(self.style.SUCCESS(f"Successfully created event: {event.title}"))

@staticmethod
def create_image():
image = Image.new("RGB", (100, 100), color="blue")
image_io = BytesIO()
image.save(image_io, format="PNG")
image_io.seek(0)

image_name = fake.uuid4() + ".png"
return ContentFile(image_io.read(), image_name)

@staticmethod
def create_schedule(event):
today = datetime.today().date()
Expand All @@ -61,19 +78,10 @@ def create_schedule(event):
end_time=end_time,
)

@staticmethod
def create_banner(event):
image = Image.new("RGB", (100, 100), color="blue")
image_io = BytesIO()
image.save(image_io, format="PNG")
image_io.seek(0)

image_name = fake.uuid4() + ".png"
image_file = ContentFile(image_io.read(), image_name)

def create_banner(self, event):
Banner.objects.create(
event=event,
image=image_file,
image=self.create_image(),
uploaded_at=fake.date_time_this_year(),
)

Expand All @@ -84,3 +92,11 @@ def create_location(event):
address=fake.address(),
google_map_link=fake.url(),
)

def create_category(self):
return Category.objects.create(
name=fake.word(),
description=fake.sentence(),
icon=self.create_image(),
is_active=fake.boolean(chance_of_getting_true=50),
)
32 changes: 32 additions & 0 deletions events/migrations/0021_category_event_categorty.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 5.1.4 on 2024-12-07 08:08

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('events', '0020_alter_eventsignup_user'),
]

operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, unique=True)),
('description', models.TextField(blank=True, null=True)),
('icon', models.ImageField(blank=True, null=True, upload_to='category_icons/')),
('is_active', models.BooleanField(default=False)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
],
),
migrations.AddField(
model_name='event',
name='categorty',
field=models.ForeignKey(default=1, limit_choices_to={'is_active': True}, on_delete=django.db.models.deletion.PROTECT, to='events.category'),
preserve_default=False,
),
]
18 changes: 18 additions & 0 deletions events/migrations/0022_rename_categorty_event_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.4 on 2024-12-07 08:27

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('events', '0021_category_event_categorty'),
]

operations = [
migrations.RenameField(
model_name='event',
old_name='categorty',
new_name='category',
),
]
Loading
Loading