diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 423a636..abb44a2 100644 Binary files a/config/__pycache__/__init__.cpython-311.pyc and b/config/__pycache__/__init__.cpython-311.pyc differ diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 96bce55..73abb21 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 0b85e94..fd771aa 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/__pycache__/wsgi.cpython-311.pyc b/config/__pycache__/wsgi.cpython-311.pyc index 9c49e09..3b6fa1f 100644 Binary files a/config/__pycache__/wsgi.cpython-311.pyc and b/config/__pycache__/wsgi.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index 291d043..b84b0e5 100644 --- a/config/settings.py +++ b/config/settings.py @@ -180,3 +180,5 @@ if EMAIL_USE_SSL: # https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' +MEDIA_URL = "/media/" +MEDIA_ROOT = os.path.join(BASE_DIR, "media") diff --git a/config/urls.py b/config/urls.py index bcfc074..cccd18f 100644 --- a/config/urls.py +++ b/config/urls.py @@ -27,3 +27,4 @@ urlpatterns = [ if settings.DEBUG: urlpatterns += static("/assets/", document_root=settings.BASE_DIR / "assets") urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 74b1112..9aed278 100644 Binary files a/core/__pycache__/__init__.cpython-311.pyc and b/core/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index a5ed392..cd3e694 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/apps.cpython-311.pyc b/core/__pycache__/apps.cpython-311.pyc index 6f131d4..cb1b371 100644 Binary files a/core/__pycache__/apps.cpython-311.pyc and b/core/__pycache__/apps.cpython-311.pyc differ diff --git a/core/__pycache__/context_processors.cpython-311.pyc b/core/__pycache__/context_processors.cpython-311.pyc index 75bf223..8da9bfe 100644 Binary files a/core/__pycache__/context_processors.cpython-311.pyc and b/core/__pycache__/context_processors.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..bd29a85 Binary files /dev/null and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index e061640..3c08c18 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 5a69659..1be8270 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 2a36fd6..c18fba3 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 8c38f3f..f9fde42 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,3 +1,19 @@ from django.contrib import admin +from .models import Category, Item, Outfit, DailySchedule -# Register your models here. +@admin.register(Category) +class CategoryAdmin(admin.ModelAdmin): + list_display = ('name',) + +@admin.register(Item) +class ItemAdmin(admin.ModelAdmin): + list_display = ('name', 'item_type', 'category') + list_filter = ('item_type', 'category') + +@admin.register(Outfit) +class OutfitAdmin(admin.ModelAdmin): + list_display = ('name', 'created_at') + +@admin.register(DailySchedule) +class DailyScheduleAdmin(admin.ModelAdmin): + list_display = ('date', 'outfit') \ No newline at end of file diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..0fafa54 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,14 @@ +from django import forms +from .models import Item, Category + +class ItemForm(forms.ModelForm): + class Meta: + model = Item + fields = ['name', 'category', 'image', 'item_type', 'tags'] + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control bg-dark text-white border-secondary', 'placeholder': 'Item Name'}), + 'category': forms.Select(attrs={'class': 'form-select bg-dark text-white border-secondary'}), + 'item_type': forms.Select(attrs={'class': 'form-select bg-dark text-white border-secondary'}), + 'tags': forms.TextInput(attrs={'class': 'form-control bg-dark text-white border-secondary', 'placeholder': 'Tags (comma-separated)'}), + 'image': forms.FileInput(attrs={'class': 'form-control bg-dark text-white border-secondary'}), + } diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..d388fda --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,53 @@ +# Generated by Django 5.2.7 on 2026-02-04 02:59 + +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')), + ('name', models.CharField(max_length=100)), + ], + options={ + 'verbose_name_plural': 'Categories', + }, + ), + migrations.CreateModel( + name='Item', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('image', models.ImageField(blank=True, null=True, upload_to='items/')), + ('item_type', models.CharField(choices=[('wardrobe', 'Wardrobe'), ('accessory', 'Accessory')], default='wardrobe', max_length=20)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.category')), + ], + ), + migrations.CreateModel( + name='Outfit', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=255)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('items', models.ManyToManyField(related_name='outfits', to='core.item')), + ], + ), + migrations.CreateModel( + name='DailySchedule', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField(unique=True)), + ('outfit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='core.outfit')), + ], + ), + ] diff --git a/core/migrations/0002_folder_outfit_folder.py b/core/migrations/0002_folder_outfit_folder.py new file mode 100644 index 0000000..129aca0 --- /dev/null +++ b/core/migrations/0002_folder_outfit_folder.py @@ -0,0 +1,27 @@ +# Generated by Django 5.2.7 on 2026-02-04 03:08 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Folder', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ], + ), + migrations.AddField( + model_name='outfit', + name='folder', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='outfits', to='core.folder'), + ), + ] diff --git a/core/migrations/0003_dailyschedule_user_folder_user_item_tags_item_user_and_more.py b/core/migrations/0003_dailyschedule_user_folder_user_item_tags_item_user_and_more.py new file mode 100644 index 0000000..7a36fb6 --- /dev/null +++ b/core/migrations/0003_dailyschedule_user_folder_user_item_tags_item_user_and_more.py @@ -0,0 +1,50 @@ +# Generated by Django 5.2.7 on 2026-02-04 03:34 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_folder_outfit_folder'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='dailyschedule', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='schedules', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='folder', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='folders', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='item', + name='tags', + field=models.CharField(blank=True, help_text='Comma-separated tags', max_length=255), + ), + migrations.AddField( + model_name='item', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='items', to=settings.AUTH_USER_MODEL), + ), + migrations.AddField( + model_name='outfit', + name='user', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='outfits', to=settings.AUTH_USER_MODEL), + ), + migrations.AlterField( + model_name='dailyschedule', + name='date', + field=models.DateField(), + ), + migrations.AlterUniqueTogether( + name='dailyschedule', + unique_together={('user', 'date')}, + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..3efe1ef Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0002_folder_outfit_folder.cpython-311.pyc b/core/migrations/__pycache__/0002_folder_outfit_folder.cpython-311.pyc new file mode 100644 index 0000000..88ac720 Binary files /dev/null and b/core/migrations/__pycache__/0002_folder_outfit_folder.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/0003_dailyschedule_user_folder_user_item_tags_item_user_and_more.cpython-311.pyc b/core/migrations/__pycache__/0003_dailyschedule_user_folder_user_item_tags_item_user_and_more.cpython-311.pyc new file mode 100644 index 0000000..9e31bf4 Binary files /dev/null and b/core/migrations/__pycache__/0003_dailyschedule_user_folder_user_item_tags_item_user_and_more.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index 9c833c8..21a48b2 100644 Binary files a/core/migrations/__pycache__/__init__.cpython-311.pyc and b/core/migrations/__pycache__/__init__.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..53a8eec 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,58 @@ from django.db import models +from django.utils import timezone +from django.contrib.auth.models import User -# Create your models here. +class Category(models.Model): + name = models.CharField(max_length=100) + # e.g., 'Pants', 'T-shirts', 'Beanies', 'Rings' + + class Meta: + verbose_name_plural = "Categories" + + def __str__(self): + return self.name + +class Item(models.Model): + ITEM_TYPES = ( + ('wardrobe', 'Wardrobe'), + ('accessory', 'Accessory'), + ) + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='items', null=True, blank=True) + name = models.CharField(max_length=255) + image = models.ImageField(upload_to='items/', blank=True, null=True) + category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, blank=True) + item_type = models.CharField(max_length=20, choices=ITEM_TYPES, default='wardrobe') + tags = models.CharField(max_length=255, blank=True, help_text="Comma-separated tags") + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.name + +class Folder(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='folders', null=True, blank=True) + name = models.CharField(max_length=100) + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.name + +class Outfit(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='outfits', null=True, blank=True) + name = models.CharField(max_length=255, blank=True) + items = models.ManyToManyField(Item, related_name='outfits') + folder = models.ForeignKey(Folder, on_delete=models.SET_NULL, null=True, blank=True, related_name='outfits') + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return self.name or f"Outfit {self.id}" + +class DailySchedule(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='schedules', null=True, blank=True) + date = models.DateField() + outfit = models.ForeignKey(Outfit, on_delete=models.SET_NULL, null=True, blank=True) + + class Meta: + unique_together = ('user', 'date') + + def __str__(self): + return f"{self.date} - {self.outfit}" \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..dc9a68b 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,25 +1,257 @@ +{% load static %} -
- -