commit 2db4593dc929a5b74f1a54e70024427906fddb2d Author: Dominic DiTaranto Date: Sat Jun 13 15:04:32 2026 -0400 init commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..a2bc589 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Summary + +# Detailed Design + +## Functionality + +### User Creates an Event + +- Fills out form +- form includes: + - Event Address + - Event Name + - Event Description + - Event Start Time + - Event End Time + - Rain Date + - Price + + - Images + - Category + - Tagging (optional) + - RSVP Needed (optio nal) + - Contact Info (optional) + - Share Email (optional) + - Event Size (how many people will go) (optional) + - Event Size Maximum (optional) +- After filling out form: + - Direct to event page + - Event page allows editing, cancelling + - share on all platforms + +### User Searches for an event +- Types in location, or read location +- Provides radius (default provided) +- Events populate +- events are clickable and show more Info +- ability to say they are going to an event (require login) +- email event to me, or others +- share on all platforms +- user can add event to list of events associated to their account +- users can filter events by category, tag, date +- users can comment on events, and post pictures of events that they went to (require login) + +## User Flow + +## Web Pages + +## DB Structure + +## API Endpoints + +## Authentication + +# Dependencies diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/__pycache__/__init__.cpython-314.pyc b/api/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..6a86f8d Binary files /dev/null and b/api/__pycache__/__init__.cpython-314.pyc differ diff --git a/api/__pycache__/admin.cpython-314.pyc b/api/__pycache__/admin.cpython-314.pyc new file mode 100644 index 0000000..2ce9faa Binary files /dev/null and b/api/__pycache__/admin.cpython-314.pyc differ diff --git a/api/__pycache__/apps.cpython-314.pyc b/api/__pycache__/apps.cpython-314.pyc new file mode 100644 index 0000000..4d7e4ba Binary files /dev/null and b/api/__pycache__/apps.cpython-314.pyc differ diff --git a/api/__pycache__/models.cpython-314.pyc b/api/__pycache__/models.cpython-314.pyc new file mode 100644 index 0000000..e5be3e4 Binary files /dev/null and b/api/__pycache__/models.cpython-314.pyc differ diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..14b89a8 --- /dev/null +++ b/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + name = "api" diff --git a/api/migrations/__init__.py b/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/migrations/__pycache__/__init__.cpython-314.pyc b/api/migrations/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..4817420 Binary files /dev/null and b/api/migrations/__pycache__/__init__.cpython-314.pyc differ diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/api/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000..7564bc8 Binary files /dev/null and b/db.sqlite3 differ diff --git a/localist/__init__.py b/localist/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/localist/__pycache__/__init__.cpython-314.pyc b/localist/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..3921022 Binary files /dev/null and b/localist/__pycache__/__init__.cpython-314.pyc differ diff --git a/localist/__pycache__/settings.cpython-314.pyc b/localist/__pycache__/settings.cpython-314.pyc new file mode 100644 index 0000000..450972d Binary files /dev/null and b/localist/__pycache__/settings.cpython-314.pyc differ diff --git a/localist/__pycache__/urls.cpython-314.pyc b/localist/__pycache__/urls.cpython-314.pyc new file mode 100644 index 0000000..55b5c55 Binary files /dev/null and b/localist/__pycache__/urls.cpython-314.pyc differ diff --git a/localist/__pycache__/wsgi.cpython-314.pyc b/localist/__pycache__/wsgi.cpython-314.pyc new file mode 100644 index 0000000..c7ddf3a Binary files /dev/null and b/localist/__pycache__/wsgi.cpython-314.pyc differ diff --git a/localist/asgi.py b/localist/asgi.py new file mode 100644 index 0000000..17de1a2 --- /dev/null +++ b/localist/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for localist project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "localist.settings") + +application = get_asgi_application() diff --git a/localist/settings.py b/localist/settings.py new file mode 100644 index 0000000..bb2a920 --- /dev/null +++ b/localist/settings.py @@ -0,0 +1,119 @@ +""" +Django settings for localist project. + +Generated by 'django-admin startproject' using Django 6.0.6. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/6.0/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = "django-insecure-pek1teheggj8zzvtcntp4-u#s_^yc$&a@3f7wi+u%8)g*2xezw" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "web", + "api", +] + +MIDDLEWARE = [ + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", +] + +ROOT_URLCONF = "localist.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + }, +] + +WSGI_APPLICATION = "localist.wsgi.application" + + +# Database +# https://docs.djangoproject.com/en/6.0/ref/settings/#databases + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", + } +} + + +# Password validation +# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/6.0/topics/i18n/ + +LANGUAGE_CODE = "en-us" + +TIME_ZONE = "UTC" + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/6.0/howto/static-files/ + +STATIC_URL = "static/" diff --git a/localist/urls.py b/localist/urls.py new file mode 100644 index 0000000..6cf30a6 --- /dev/null +++ b/localist/urls.py @@ -0,0 +1,23 @@ +""" +URL configuration for localist project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/6.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" + +from django.contrib import admin +from django.urls import path + +urlpatterns = [ + path("admin/", admin.site.urls), +] diff --git a/localist/wsgi.py b/localist/wsgi.py new file mode 100644 index 0000000..36606b4 --- /dev/null +++ b/localist/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for localist project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/6.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "localist.settings") + +application = get_wsgi_application() diff --git a/web/__init__.py b/web/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/__pycache__/__init__.cpython-314.pyc b/web/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..f290d65 Binary files /dev/null and b/web/__pycache__/__init__.cpython-314.pyc differ diff --git a/web/__pycache__/admin.cpython-314.pyc b/web/__pycache__/admin.cpython-314.pyc new file mode 100644 index 0000000..8016d6e Binary files /dev/null and b/web/__pycache__/admin.cpython-314.pyc differ diff --git a/web/__pycache__/apps.cpython-314.pyc b/web/__pycache__/apps.cpython-314.pyc new file mode 100644 index 0000000..17ddc49 Binary files /dev/null and b/web/__pycache__/apps.cpython-314.pyc differ diff --git a/web/admin.py b/web/admin.py new file mode 100644 index 0000000..efb705c --- /dev/null +++ b/web/admin.py @@ -0,0 +1,12 @@ +from django.contrib import admin +from web.models.category import Category, CategoryAdmin +from web.models.event import Event, EventAdmin +from web.models.event_category import EventCategory, EventCategoryAdmin +from web.models.event_tag import EventTag, EventTagAdmin +from web.models.tag import Tag, TagAdmin + +admin.site.register(Category, CategoryAdmin) +admin.site.register(Event, EventAdmin) +admin.site.register(EventCategory, EventCategoryAdmin) +admin.site.register(EventTag, EventTagAdmin) +admin.site.register(Tag, TagAdmin) diff --git a/web/apps.py b/web/apps.py new file mode 100644 index 0000000..2bc88a3 --- /dev/null +++ b/web/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class WebConfig(AppConfig): + name = "web" diff --git a/web/migrations/0001_initial.py b/web/migrations/0001_initial.py new file mode 100644 index 0000000..c996f4e --- /dev/null +++ b/web/migrations/0001_initial.py @@ -0,0 +1,169 @@ +# Generated by Django 6.0.6 on 2026-06-13 19:01 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [] + + operations = [ + migrations.CreateModel( + name="Category", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("active", models.BooleanField(default=True)), + ("name", models.CharField()), + ("description", models.TextField()), + ], + options={ + "db_table": "category", + }, + ), + migrations.CreateModel( + name="Event", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("active", models.BooleanField(default=True)), + ("name", models.CharField()), + ("description", models.TextField()), + ("url", models.URLField()), + ("address", models.CharField()), + ( + "status", + models.CharField( + choices=[ + ("scheduled", "Scheduled"), + ("completed", "Completed"), + ("canceled", "Canceled"), + ], + default="scheduled", + max_length=20, + ), + ), + ( + "price", + models.DecimalField( + blank=True, decimal_places=2, default=None, max_digits=10 + ), + ), + ("require_rsvp", models.BooleanField()), + ("start_time", models.DateTimeField()), + ("end_time", models.DateTimeField()), + ("rain_date", models.DateTimeField()), + ("email", models.EmailField(max_length=254)), + ("phone_number", models.CharField(blank=True, default=None)), + ], + options={ + "db_table": "events", + }, + ), + migrations.CreateModel( + name="Tag", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("active", models.BooleanField(default=True)), + ("name", models.CharField()), + ], + options={ + "db_table": "tag", + }, + ), + migrations.CreateModel( + name="EventCategory", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("active", models.BooleanField(default=True)), + ( + "category", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="web.category" + ), + ), + ( + "event", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="web.event" + ), + ), + ], + options={ + "db_table": "event_categories", + }, + ), + migrations.CreateModel( + name="EventTag", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("active", models.BooleanField(default=True)), + ( + "event", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="web.event" + ), + ), + ( + "tag", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="web.tag" + ), + ), + ], + options={ + "db_table": "event_tags", + }, + ), + ] diff --git a/web/migrations/__init__.py b/web/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/web/migrations/__pycache__/0001_initial.cpython-314.pyc b/web/migrations/__pycache__/0001_initial.cpython-314.pyc new file mode 100644 index 0000000..ad2237e Binary files /dev/null and b/web/migrations/__pycache__/0001_initial.cpython-314.pyc differ diff --git a/web/migrations/__pycache__/__init__.cpython-314.pyc b/web/migrations/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000..f405489 Binary files /dev/null and b/web/migrations/__pycache__/__init__.cpython-314.pyc differ diff --git a/web/models/__pycache__/base.cpython-314.pyc b/web/models/__pycache__/base.cpython-314.pyc new file mode 100644 index 0000000..5a8c9d7 Binary files /dev/null and b/web/models/__pycache__/base.cpython-314.pyc differ diff --git a/web/models/__pycache__/category.cpython-314.pyc b/web/models/__pycache__/category.cpython-314.pyc new file mode 100644 index 0000000..e019287 Binary files /dev/null and b/web/models/__pycache__/category.cpython-314.pyc differ diff --git a/web/models/__pycache__/event.cpython-314.pyc b/web/models/__pycache__/event.cpython-314.pyc new file mode 100644 index 0000000..12063e6 Binary files /dev/null and b/web/models/__pycache__/event.cpython-314.pyc differ diff --git a/web/models/__pycache__/event_category.cpython-314.pyc b/web/models/__pycache__/event_category.cpython-314.pyc new file mode 100644 index 0000000..5d911e9 Binary files /dev/null and b/web/models/__pycache__/event_category.cpython-314.pyc differ diff --git a/web/models/__pycache__/event_tag.cpython-314.pyc b/web/models/__pycache__/event_tag.cpython-314.pyc new file mode 100644 index 0000000..55e45ce Binary files /dev/null and b/web/models/__pycache__/event_tag.cpython-314.pyc differ diff --git a/web/models/__pycache__/tag.cpython-314.pyc b/web/models/__pycache__/tag.cpython-314.pyc new file mode 100644 index 0000000..8e2b693 Binary files /dev/null and b/web/models/__pycache__/tag.cpython-314.pyc differ diff --git a/web/models/base.py b/web/models/base.py new file mode 100644 index 0000000..2b5a850 --- /dev/null +++ b/web/models/base.py @@ -0,0 +1,10 @@ +from django.db import models + + +class BaseModel(models.Model): + created_at = models.DateTimeField(blank=True, null=True, auto_now_add=True) + updated_at = models.DateTimeField(blank=True, null=True, auto_now=True) + active = models.BooleanField(default=True) + + class Meta: + abstract = True diff --git a/web/models/category.py b/web/models/category.py new file mode 100644 index 0000000..d092fa1 --- /dev/null +++ b/web/models/category.py @@ -0,0 +1,23 @@ +from django.db import models +from django.contrib import admin +from web.models.base import BaseModel + + +class Category(BaseModel): + name = models.CharField() + description = models.TextField() + + class Meta: + db_table = 'category' + + +class CategoryAdmin(admin.ModelAdmin): + search_fields = ( + 'name', + 'description' + ) + + list_display = ( + 'name', + 'description', + ) diff --git a/web/models/event.py b/web/models/event.py new file mode 100644 index 0000000..c702866 --- /dev/null +++ b/web/models/event.py @@ -0,0 +1,58 @@ +from django.db import models +from django.contrib import admin +from web.models.base import BaseModel +from enum import StrEnum + + + +class Event(BaseModel): + class Status(models.TextChoices): + SCHEDULED = 'scheduled', 'Scheduled' + COMPLETED = 'completed', 'Completed' + CANCELED = 'canceled', 'Canceled' + + name = models.CharField() + description = models.TextField() + url = models.URLField() + address = models.CharField() + status = models.CharField(max_length=20, choices=Status.choices, default=Status.SCHEDULED) + price = models.DecimalField(max_digits=10, default=None, blank=True, decimal_places=2) + require_rsvp = models.BooleanField() + + start_time = models.DateTimeField() + end_time = models.DateTimeField() + rain_date = models.DateTimeField() + + email = models.EmailField() + phone_number = models.CharField(default=None, blank=True) + + class Meta: + db_table = 'events' + + +class EventAdmin(admin.ModelAdmin): + search_fields = ( + 'name', + 'description', + 'start_time', + 'end_time', + 'rain_date', + 'url', + 'address', + 'status', + 'price', + 'require_rsvp', + ) + + list_display = ( + 'name', + 'description', + 'start_time', + 'end_time', + 'rain_date', + 'url', + 'address', + 'status', + 'price', + 'require_rsvp', + ) diff --git a/web/models/event_category.py b/web/models/event_category.py new file mode 100644 index 0000000..04c9522 --- /dev/null +++ b/web/models/event_category.py @@ -0,0 +1,25 @@ +from django.db import models +from django.contrib import admin +from web.models.base import BaseModel +from web.models.event import Event +from web.models.category import Category + + +class EventCategory(BaseModel): + event = models.ForeignKey(Event, on_delete=models.CASCADE) + category = models.ForeignKey(Category, on_delete=models.CASCADE) + + class Meta: + db_table = 'event_categories' + + +class EventCategoryAdmin(admin.ModelAdmin): + search_fields = ( + 'event', + 'category', + ) + + list_display = ( + 'event', + 'category', + ) diff --git a/web/models/event_tag.py b/web/models/event_tag.py new file mode 100644 index 0000000..df7e8c3 --- /dev/null +++ b/web/models/event_tag.py @@ -0,0 +1,25 @@ +from django.db import models +from django.contrib import admin +from web.models.base import BaseModel +from web.models.event import Event +from web.models.tag import Tag + + +class EventTag(BaseModel): + event = models.ForeignKey(Event, on_delete=models.CASCADE) + tag = models.ForeignKey(Tag, on_delete=models.CASCADE) + + class Meta: + db_table = 'event_tags' + + +class EventTagAdmin(admin.ModelAdmin): + search_fields = ( + 'event', + 'tag', + ) + + list_display = ( + 'event', + 'tag', + ) diff --git a/web/models/tag.py b/web/models/tag.py new file mode 100644 index 0000000..1d0b923 --- /dev/null +++ b/web/models/tag.py @@ -0,0 +1,20 @@ +from django.db import models +from django.contrib import admin +from web.models.base import BaseModel + + +class Tag(BaseModel): + name = models.CharField() + + class Meta: + db_table = 'tag' + + +class TagAdmin(admin.ModelAdmin): + search_fields = ( + 'name', + ) + + list_display = ( + 'name', + ) diff --git a/web/tests.py b/web/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/web/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/web/views.py b/web/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/web/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.