mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 09:11:08 -05:00
yay
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,4 +4,4 @@
|
|||||||
venv
|
venv
|
||||||
/venv
|
/venv
|
||||||
./venv
|
./venv
|
||||||
venv/
|
venv/sour
|
||||||
Binary file not shown.
BIN
accounts/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/adapters.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/adapters.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/admin.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/apps.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/models.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/signals.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/signals.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/urls.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/urls.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
accounts/__pycache__/views.cpython-312.pyc
Normal file
BIN
accounts/__pycache__/views.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
85
accounts/management/commands/reset_db.py
Normal file
85
accounts/management/commands/reset_db.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.db import connection
|
||||||
|
from django.contrib.auth.hashers import make_password
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Reset database and create admin user'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
self.stdout.write('Resetting database...')
|
||||||
|
|
||||||
|
# Drop all tables
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("""
|
||||||
|
DO $$ DECLARE
|
||||||
|
r RECORD;
|
||||||
|
BEGIN
|
||||||
|
FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
|
||||||
|
EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
|
||||||
|
END LOOP;
|
||||||
|
END $$;
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Reset sequences
|
||||||
|
cursor.execute("""
|
||||||
|
DO $$ DECLARE
|
||||||
|
r RECORD;
|
||||||
|
BEGIN
|
||||||
|
FOR r IN (SELECT sequencename FROM pg_sequences WHERE schemaname = current_schema()) LOOP
|
||||||
|
EXECUTE 'ALTER SEQUENCE ' || quote_ident(r.sequencename) || ' RESTART WITH 1';
|
||||||
|
END LOOP;
|
||||||
|
END $$;
|
||||||
|
""")
|
||||||
|
|
||||||
|
self.stdout.write('All tables dropped and sequences reset.')
|
||||||
|
|
||||||
|
# Run migrations
|
||||||
|
from django.core.management import call_command
|
||||||
|
call_command('migrate')
|
||||||
|
|
||||||
|
self.stdout.write('Migrations applied.')
|
||||||
|
|
||||||
|
# Create superuser using raw SQL
|
||||||
|
try:
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
# Create user
|
||||||
|
user_id = str(uuid.uuid4())[:10]
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO accounts_user (
|
||||||
|
username, password, email, is_superuser, is_staff,
|
||||||
|
is_active, date_joined, user_id, first_name,
|
||||||
|
last_name, role, is_banned, ban_reason,
|
||||||
|
theme_preference
|
||||||
|
) VALUES (
|
||||||
|
'admin', %s, 'admin@thrillwiki.com', true, true,
|
||||||
|
true, NOW(), %s, '', '', 'SUPERUSER', false, '',
|
||||||
|
'light'
|
||||||
|
) RETURNING id;
|
||||||
|
""", [make_password('admin'), user_id])
|
||||||
|
|
||||||
|
user_db_id = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
# Create profile
|
||||||
|
profile_id = str(uuid.uuid4())[:10]
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO accounts_userprofile (
|
||||||
|
profile_id, display_name, pronouns, bio,
|
||||||
|
twitter, instagram, youtube, discord,
|
||||||
|
coaster_credits, dark_ride_credits,
|
||||||
|
flat_ride_credits, water_ride_credits,
|
||||||
|
user_id, avatar
|
||||||
|
) VALUES (
|
||||||
|
%s, 'Admin', 'they/them', 'ThrillWiki Administrator',
|
||||||
|
'', '', '', '',
|
||||||
|
0, 0, 0, 0,
|
||||||
|
%s, ''
|
||||||
|
);
|
||||||
|
""", [profile_id, user_db_id])
|
||||||
|
|
||||||
|
self.stdout.write('Superuser created.')
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(self.style.ERROR(f'Error creating superuser: {str(e)}'))
|
||||||
|
raise
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS('Database reset complete.'))
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.1.2 on 2024-10-28 20:17
|
# Generated by Django 5.1.2 on 2024-10-28 21:50
|
||||||
|
|
||||||
import django.contrib.auth.models
|
import django.contrib.auth.models
|
||||||
import django.contrib.auth.validators
|
import django.contrib.auth.validators
|
||||||
@@ -13,121 +13,345 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('auth', '0012_alter_user_first_name_max_length'),
|
("auth", "0012_alter_user_first_name_max_length"),
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
("contenttypes", "0002_remove_content_type_name"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='User',
|
name="User",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('password', models.CharField(max_length=128, verbose_name='password')),
|
"id",
|
||||||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
|
models.BigAutoField(
|
||||||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
|
auto_created=True,
|
||||||
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
|
primary_key=True,
|
||||||
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
|
serialize=False,
|
||||||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
|
verbose_name="ID",
|
||||||
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
|
),
|
||||||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
|
),
|
||||||
('user_id', models.CharField(editable=False, help_text='Unique identifier for this user that remains constant even if the username changes', max_length=10, unique=True)),
|
("password", models.CharField(max_length=128, verbose_name="password")),
|
||||||
('first_name', models.CharField(default='', max_length=150, verbose_name='first name')),
|
(
|
||||||
('last_name', models.CharField(default='', max_length=150, verbose_name='last name')),
|
"last_login",
|
||||||
('role', models.CharField(choices=[('USER', 'User'), ('MODERATOR', 'Moderator'), ('ADMIN', 'Admin'), ('SUPERUSER', 'Superuser')], default='USER', max_length=10)),
|
models.DateTimeField(
|
||||||
('is_banned', models.BooleanField(default=False)),
|
blank=True, null=True, verbose_name="last login"
|
||||||
('ban_reason', models.TextField(blank=True)),
|
),
|
||||||
('ban_date', models.DateTimeField(blank=True, null=True)),
|
),
|
||||||
('pending_email', models.EmailField(blank=True, max_length=254, null=True)),
|
(
|
||||||
('theme_preference', models.CharField(choices=[('light', 'Light'), ('dark', 'Dark')], default='light', max_length=5)),
|
"is_superuser",
|
||||||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
|
models.BooleanField(
|
||||||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
|
default=False,
|
||||||
|
help_text="Designates that this user has all permissions without explicitly assigning them.",
|
||||||
|
verbose_name="superuser status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"username",
|
||||||
|
models.CharField(
|
||||||
|
error_messages={
|
||||||
|
"unique": "A user with that username already exists."
|
||||||
|
},
|
||||||
|
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
|
||||||
|
max_length=150,
|
||||||
|
unique=True,
|
||||||
|
validators=[
|
||||||
|
django.contrib.auth.validators.UnicodeUsernameValidator()
|
||||||
|
],
|
||||||
|
verbose_name="username",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"email",
|
||||||
|
models.EmailField(
|
||||||
|
blank=True, max_length=254, verbose_name="email address"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"is_staff",
|
||||||
|
models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
help_text="Designates whether the user can log into this admin site.",
|
||||||
|
verbose_name="staff status",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"is_active",
|
||||||
|
models.BooleanField(
|
||||||
|
default=True,
|
||||||
|
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
|
||||||
|
verbose_name="active",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"date_joined",
|
||||||
|
models.DateTimeField(
|
||||||
|
default=django.utils.timezone.now, verbose_name="date joined"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user_id",
|
||||||
|
models.CharField(
|
||||||
|
editable=False,
|
||||||
|
help_text="Unique identifier for this user that remains constant even if the username changes",
|
||||||
|
max_length=10,
|
||||||
|
unique=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"first_name",
|
||||||
|
models.CharField(
|
||||||
|
default="", max_length=150, verbose_name="first name"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"last_name",
|
||||||
|
models.CharField(
|
||||||
|
default="", max_length=150, verbose_name="last name"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"role",
|
||||||
|
models.CharField(
|
||||||
|
choices=[
|
||||||
|
("USER", "User"),
|
||||||
|
("MODERATOR", "Moderator"),
|
||||||
|
("ADMIN", "Admin"),
|
||||||
|
("SUPERUSER", "Superuser"),
|
||||||
|
],
|
||||||
|
default="USER",
|
||||||
|
max_length=10,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("is_banned", models.BooleanField(default=False)),
|
||||||
|
("ban_reason", models.TextField(blank=True)),
|
||||||
|
("ban_date", models.DateTimeField(blank=True, null=True)),
|
||||||
|
(
|
||||||
|
"pending_email",
|
||||||
|
models.EmailField(blank=True, max_length=254, null=True),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"theme_preference",
|
||||||
|
models.CharField(
|
||||||
|
choices=[("light", "Light"), ("dark", "Dark")],
|
||||||
|
default="light",
|
||||||
|
max_length=5,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"groups",
|
||||||
|
models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
|
||||||
|
related_name="user_set",
|
||||||
|
related_query_name="user",
|
||||||
|
to="auth.group",
|
||||||
|
verbose_name="groups",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"user_permissions",
|
||||||
|
models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
help_text="Specific permissions for this user.",
|
||||||
|
related_name="user_set",
|
||||||
|
related_query_name="user",
|
||||||
|
to="auth.permission",
|
||||||
|
verbose_name="user permissions",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'user',
|
"verbose_name": "user",
|
||||||
'verbose_name_plural': 'users',
|
"verbose_name_plural": "users",
|
||||||
'abstract': False,
|
"abstract": False,
|
||||||
},
|
},
|
||||||
managers=[
|
managers=[
|
||||||
('objects', django.contrib.auth.models.UserManager()),
|
("objects", django.contrib.auth.models.UserManager()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='EmailVerification',
|
name="EmailVerification",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('token', models.CharField(max_length=64, unique=True)),
|
"id",
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
models.BigAutoField(
|
||||||
('last_sent', models.DateTimeField(auto_now_add=True)),
|
auto_created=True,
|
||||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("token", models.CharField(max_length=64, unique=True)),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("last_sent", models.DateTimeField(auto_now_add=True)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'Email Verification',
|
"verbose_name": "Email Verification",
|
||||||
'verbose_name_plural': 'Email Verifications',
|
"verbose_name_plural": "Email Verifications",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='PasswordReset',
|
name="PasswordReset",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('token', models.CharField(max_length=64)),
|
"id",
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
models.BigAutoField(
|
||||||
('expires_at', models.DateTimeField()),
|
auto_created=True,
|
||||||
('used', models.BooleanField(default=False)),
|
primary_key=True,
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("token", models.CharField(max_length=64)),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("expires_at", models.DateTimeField()),
|
||||||
|
("used", models.BooleanField(default=False)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'verbose_name': 'Password Reset',
|
"verbose_name": "Password Reset",
|
||||||
'verbose_name_plural': 'Password Resets',
|
"verbose_name_plural": "Password Resets",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='TopList',
|
name="TopList",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('title', models.CharField(max_length=100)),
|
"id",
|
||||||
('category', models.CharField(choices=[('RC', 'Roller Coaster'), ('DR', 'Dark Ride'), ('FR', 'Flat Ride'), ('WR', 'Water Ride'), ('PK', 'Park')], max_length=2)),
|
models.BigAutoField(
|
||||||
('description', models.TextField(blank=True)),
|
auto_created=True,
|
||||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
primary_key=True,
|
||||||
('updated_at', models.DateTimeField(auto_now=True)),
|
serialize=False,
|
||||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='top_lists', to=settings.AUTH_USER_MODEL)),
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("title", models.CharField(max_length=100)),
|
||||||
|
(
|
||||||
|
"category",
|
||||||
|
models.CharField(
|
||||||
|
choices=[
|
||||||
|
("RC", "Roller Coaster"),
|
||||||
|
("DR", "Dark Ride"),
|
||||||
|
("FR", "Flat Ride"),
|
||||||
|
("WR", "Water Ride"),
|
||||||
|
("PK", "Park"),
|
||||||
|
],
|
||||||
|
max_length=2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("description", models.TextField(blank=True)),
|
||||||
|
("created_at", models.DateTimeField(auto_now_add=True)),
|
||||||
|
("updated_at", models.DateTimeField(auto_now=True)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="top_lists",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ['-updated_at'],
|
"ordering": ["-updated_at"],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='UserProfile',
|
name="UserProfile",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('profile_id', models.CharField(editable=False, help_text='Unique identifier for this profile that remains constant', max_length=10, unique=True)),
|
"id",
|
||||||
('display_name', models.CharField(help_text='This is the name that will be displayed on the site', max_length=50, unique=True)),
|
models.BigAutoField(
|
||||||
('avatar', models.ImageField(blank=True, upload_to='avatars/')),
|
auto_created=True,
|
||||||
('pronouns', models.CharField(blank=True, max_length=50)),
|
primary_key=True,
|
||||||
('bio', models.TextField(blank=True, max_length=500)),
|
serialize=False,
|
||||||
('twitter', models.URLField(blank=True)),
|
verbose_name="ID",
|
||||||
('instagram', models.URLField(blank=True)),
|
),
|
||||||
('youtube', models.URLField(blank=True)),
|
),
|
||||||
('discord', models.CharField(blank=True, max_length=100)),
|
(
|
||||||
('coaster_credits', models.IntegerField(default=0)),
|
"profile_id",
|
||||||
('dark_ride_credits', models.IntegerField(default=0)),
|
models.CharField(
|
||||||
('flat_ride_credits', models.IntegerField(default=0)),
|
editable=False,
|
||||||
('water_ride_credits', models.IntegerField(default=0)),
|
help_text="Unique identifier for this profile that remains constant",
|
||||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
|
max_length=10,
|
||||||
|
unique=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"display_name",
|
||||||
|
models.CharField(
|
||||||
|
help_text="This is the name that will be displayed on the site",
|
||||||
|
max_length=50,
|
||||||
|
unique=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("avatar", models.ImageField(blank=True, upload_to="avatars/")),
|
||||||
|
("pronouns", models.CharField(blank=True, max_length=50)),
|
||||||
|
("bio", models.TextField(blank=True, max_length=500)),
|
||||||
|
("twitter", models.URLField(blank=True)),
|
||||||
|
("instagram", models.URLField(blank=True)),
|
||||||
|
("youtube", models.URLField(blank=True)),
|
||||||
|
("discord", models.CharField(blank=True, max_length=100)),
|
||||||
|
("coaster_credits", models.IntegerField(default=0)),
|
||||||
|
("dark_ride_credits", models.IntegerField(default=0)),
|
||||||
|
("flat_ride_credits", models.IntegerField(default=0)),
|
||||||
|
("water_ride_credits", models.IntegerField(default=0)),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="profile",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='TopListItem',
|
name="TopListItem",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
(
|
||||||
('object_id', models.PositiveIntegerField()),
|
"id",
|
||||||
('rank', models.PositiveIntegerField()),
|
models.BigAutoField(
|
||||||
('notes', models.TextField(blank=True)),
|
auto_created=True,
|
||||||
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
|
primary_key=True,
|
||||||
('top_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='accounts.toplist')),
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("object_id", models.PositiveIntegerField()),
|
||||||
|
("rank", models.PositiveIntegerField()),
|
||||||
|
("notes", models.TextField(blank=True)),
|
||||||
|
(
|
||||||
|
"content_type",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
to="contenttypes.contenttype",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"top_list",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="items",
|
||||||
|
to="accounts.toplist",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ['rank'],
|
"ordering": ["rank"],
|
||||||
'unique_together': {('top_list', 'rank')},
|
"unique_together": {("top_list", "rank")},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
Binary file not shown.
BIN
accounts/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
BIN
accounts/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
accounts/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
accounts/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
120
assets/css/src/input.css
Normal file
120
assets/css/src/input.css
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
.btn-primary {
|
||||||
|
@apply inline-flex items-center px-6 py-2.5 border border-transparent rounded-full shadow-md text-sm font-medium text-white bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
@apply inline-flex items-center px-6 py-2.5 border border-gray-200 dark:border-gray-700 rounded-full shadow-md text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-105 transition-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
@apply flex items-center px-6 py-2.5 rounded-lg font-medium text-gray-700 dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary transition-all border border-transparent hover:border-primary/20 dark:hover:border-primary/30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link i {
|
||||||
|
@apply mr-3 text-lg text-gray-500 transition-colors dark:text-gray-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link:hover i {
|
||||||
|
@apply text-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-link {
|
||||||
|
@apply flex items-center px-6 py-3 text-gray-700 transition-all border border-transparent rounded-lg dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary hover:border-primary/20 dark:hover:border-primary/30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-link i {
|
||||||
|
@apply mr-3 text-lg text-gray-500 dark:text-gray-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
@apply flex items-center w-full px-4 py-3 text-sm text-gray-700 transition-all dark:text-gray-200 hover:bg-primary/10 dark:hover:bg-primary/20 hover:text-primary dark:hover:text-primary first:rounded-t-lg last:rounded-b-lg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item i {
|
||||||
|
@apply mr-3 text-base text-gray-500 dark:text-gray-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
@apply w-full px-4 py-3 text-gray-900 transition-all border border-gray-200 rounded-lg shadow-sm dark:border-gray-700 bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm dark:text-white focus:ring-2 focus:ring-primary/50 focus:border-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
@apply block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-hint {
|
||||||
|
@apply mt-2 space-y-1 text-sm text-gray-500 dark:text-gray-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-error {
|
||||||
|
@apply mt-2 text-sm text-red-600 dark:text-red-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Auth Card Styles */
|
||||||
|
.auth-card {
|
||||||
|
@apply w-full max-w-md p-8 mx-auto border shadow-xl bg-white/90 dark:bg-gray-800/90 rounded-2xl backdrop-blur-sm border-gray-200/50 dark:border-gray-700/50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-title {
|
||||||
|
@apply mb-8 text-2xl font-bold text-center text-transparent bg-gradient-to-r from-primary to-secondary bg-clip-text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-divider {
|
||||||
|
@apply relative my-6 text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-divider::before,
|
||||||
|
.auth-divider::after {
|
||||||
|
@apply absolute top-1/2 w-1/3 border-t border-gray-200 dark:border-gray-700 content-[''];
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-divider::before {
|
||||||
|
@apply left-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-divider::after {
|
||||||
|
@apply right-0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.auth-divider span {
|
||||||
|
@apply px-4 text-sm text-gray-500 dark:text-gray-400 bg-white/90 dark:bg-gray-800/90;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Social Login Buttons */
|
||||||
|
.btn-social {
|
||||||
|
@apply w-full flex items-center justify-center px-6 py-3 border border-gray-200 dark:border-gray-700 rounded-lg shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary/50 transform hover:scale-[1.02] transition-all mb-3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-discord {
|
||||||
|
@apply bg-[#5865F2] hover:bg-[#4752C4] text-white border-transparent shadow-[#5865F2]/20;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-google {
|
||||||
|
@apply text-gray-700 bg-white border-gray-200 hover:bg-gray-50 shadow-gray-200/50 dark:shadow-gray-900/50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
@apply p-4 mb-4 shadow-lg rounded-xl backdrop-blur-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-success {
|
||||||
|
@apply text-green-800 border border-green-200 bg-green-100/90 dark:bg-green-800/30 dark:text-green-100 dark:border-green-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-error {
|
||||||
|
@apply text-red-800 border border-red-200 bg-red-100/90 dark:bg-red-800/30 dark:text-red-100 dark:border-red-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-warning {
|
||||||
|
@apply text-yellow-800 border border-yellow-200 bg-yellow-100/90 dark:bg-yellow-800/30 dark:text-yellow-100 dark:border-yellow-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-info {
|
||||||
|
@apply text-blue-800 border border-blue-200 bg-blue-100/90 dark:bg-blue-800/30 dark:text-blue-100 dark:border-blue-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
BIN
companies/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
companies/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
companies/__pycache__/admin.cpython-312.pyc
Normal file
BIN
companies/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
companies/__pycache__/apps.cpython-312.pyc
Normal file
BIN
companies/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
companies/__pycache__/models.cpython-312.pyc
Normal file
BIN
companies/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
companies/__pycache__/signals.cpython-312.pyc
Normal file
BIN
companies/__pycache__/signals.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
companies/__pycache__/urls.cpython-312.pyc
Normal file
BIN
companies/__pycache__/urls.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
companies/__pycache__/views.cpython-312.pyc
Normal file
BIN
companies/__pycache__/views.cpython-312.pyc
Normal file
Binary file not shown.
@@ -4,14 +4,14 @@ from .models import Company, Manufacturer
|
|||||||
|
|
||||||
@admin.register(Company)
|
@admin.register(Company)
|
||||||
class CompanyAdmin(SimpleHistoryAdmin):
|
class CompanyAdmin(SimpleHistoryAdmin):
|
||||||
list_display = ('name', 'headquarters', 'website', 'created_at')
|
list_display = ('id', 'name', 'headquarters', 'website', 'created_at')
|
||||||
search_fields = ('name', 'headquarters', 'description')
|
search_fields = ('name', 'headquarters', 'description')
|
||||||
prepopulated_fields = {'slug': ('name',)}
|
prepopulated_fields = {'slug': ('name',)}
|
||||||
readonly_fields = ('created_at', 'updated_at')
|
readonly_fields = ('created_at', 'updated_at')
|
||||||
|
|
||||||
@admin.register(Manufacturer)
|
@admin.register(Manufacturer)
|
||||||
class ManufacturerAdmin(SimpleHistoryAdmin):
|
class ManufacturerAdmin(SimpleHistoryAdmin):
|
||||||
list_display = ('name', 'headquarters', 'website', 'created_at')
|
list_display = ('id', 'name', 'headquarters', 'website', 'created_at')
|
||||||
search_fields = ('name', 'headquarters', 'description')
|
search_fields = ('name', 'headquarters', 'description')
|
||||||
prepopulated_fields = {'slug': ('name',)}
|
prepopulated_fields = {'slug': ('name',)}
|
||||||
readonly_fields = ('created_at', 'updated_at')
|
readonly_fields = ('created_at', 'updated_at')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 5.1.2 on 2024-10-28 20:25
|
# Generated manually
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
@@ -31,22 +31,22 @@ class Migration(migrations.Migration):
|
|||||||
field=models.PositiveIntegerField(default=0),
|
field=models.PositiveIntegerField(default=0),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='historicalmanufacturer',
|
model_name='manufacturer',
|
||||||
name='total_rides',
|
name='total_rides',
|
||||||
field=models.PositiveIntegerField(default=0),
|
field=models.PositiveIntegerField(default=0),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='historicalmanufacturer',
|
model_name='manufacturer',
|
||||||
name='total_roller_coasters',
|
name='total_roller_coasters',
|
||||||
field=models.PositiveIntegerField(default=0),
|
field=models.PositiveIntegerField(default=0),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='manufacturer',
|
model_name='historicalmanufacturer',
|
||||||
name='total_rides',
|
name='total_rides',
|
||||||
field=models.PositiveIntegerField(default=0),
|
field=models.PositiveIntegerField(default=0),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='manufacturer',
|
model_name='historicalmanufacturer',
|
||||||
name='total_roller_coasters',
|
name='total_roller_coasters',
|
||||||
field=models.PositiveIntegerField(default=0),
|
field=models.PositiveIntegerField(default=0),
|
||||||
),
|
),
|
||||||
13
companies/migrations/0003_remove_total_parks.py
Normal file
13
companies/migrations/0003_remove_total_parks.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('companies', '0002_stats_fields'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='company',
|
||||||
|
name='total_parks',
|
||||||
|
),
|
||||||
|
]
|
||||||
14
companies/migrations/0004_add_total_parks.py
Normal file
14
companies/migrations/0004_add_total_parks.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('companies', '0003_remove_total_parks'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='company',
|
||||||
|
name='total_parks',
|
||||||
|
field=models.PositiveIntegerField(default=0),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
BIN
companies/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
BIN
companies/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
companies/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
companies/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
core/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/__pycache__/admin.cpython-312.pyc
Normal file
BIN
core/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/__pycache__/apps.cpython-312.pyc
Normal file
BIN
core/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/__pycache__/models.cpython-312.pyc
Normal file
BIN
core/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/__pycache__/views.cpython-312.pyc
Normal file
BIN
core/__pycache__/views.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
BIN
core/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
core/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
core/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
email_service/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
email_service/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
email_service/__pycache__/admin.cpython-312.pyc
Normal file
BIN
email_service/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
email_service/__pycache__/apps.cpython-312.pyc
Normal file
BIN
email_service/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
email_service/__pycache__/models.cpython-312.pyc
Normal file
BIN
email_service/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
email_service/__pycache__/services.cpython-312.pyc
Normal file
BIN
email_service/__pycache__/services.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
email_service/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
email_service/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
media/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/__pycache__/admin.cpython-312.pyc
Normal file
BIN
media/__pycache__/admin.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/__pycache__/apps.cpython-312.pyc
Normal file
BIN
media/__pycache__/apps.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/__pycache__/models.cpython-312.pyc
Normal file
BIN
media/__pycache__/models.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
BIN
media/migrations/__pycache__/0001_initial.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
media/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
media/migrations/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user