diff --git a/config/__pycache__/__init__.cpython-311.pyc b/config/__pycache__/__init__.cpython-311.pyc index 423a636..033bbd2 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..cfe6ff2 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..80ed711 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..14e1012 100644 Binary files a/config/__pycache__/wsgi.cpython-311.pyc and b/config/__pycache__/wsgi.cpython-311.pyc differ diff --git a/core/__pycache__/__init__.cpython-311.pyc b/core/__pycache__/__init__.cpython-311.pyc index 74b1112..b38c29f 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..e7f55d3 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..7b8c00f 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..7787788 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..7a5501f 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..837f00b 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..4fbc8c4 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..da2864b 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..44d25c1 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,3 +1,15 @@ from django.contrib import admin +from .models import Category, Transaction -# Register your models here. +@admin.register(Category) +class CategoryAdmin(admin.ModelAdmin): + list_display = ('name', 'type', 'icon') + list_filter = ('type',) + search_fields = ('name',) + +@admin.register(Transaction) +class TransactionAdmin(admin.ModelAdmin): + list_display = ('date', 'type', 'amount', 'category', 'description') + list_filter = ('type', 'category', 'date') + search_fields = ('description',) + date_hierarchy = 'date' \ No newline at end of file diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..43e7886 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,18 @@ +from django import forms +from .models import Transaction, Category + +class TransactionForm(forms.ModelForm): + class Meta: + model = Transaction + fields = ['amount', 'type', 'category', 'date', 'description'] + widgets = { + 'date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}), + 'amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01', 'placeholder': '0.00'}), + 'type': forms.Select(attrs={'class': 'form-select'}), + 'category': forms.Select(attrs={'class': 'form-select'}), + 'description': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'What was this for?'}), + } + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['category'].queryset = Category.objects.all() diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..65ff391 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,40 @@ +# Generated by Django 5.2.7 on 2026-02-01 13:44 + +import django.db.models.deletion +import django.utils.timezone +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)), + ('type', models.CharField(choices=[('income', 'Income'), ('expense', 'Expense')], default='expense', max_length=10)), + ('icon', models.CharField(blank=True, help_text='FontAwesome icon name (e.g., fa-utensils)', max_length=50, null=True)), + ], + options={ + 'verbose_name_plural': 'Categories', + }, + ), + migrations.CreateModel( + name='Transaction', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.DecimalField(decimal_places=2, max_digits=10)), + ('date', models.DateField(default=django.utils.timezone.now)), + ('description', models.CharField(blank=True, max_length=255)), + ('type', models.CharField(choices=[('income', 'Income'), ('expense', 'Expense')], default='expense', max_length=10)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('category', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='transactions', to='core.category')), + ], + ), + ] 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..6f3bfa6 Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/migrations/__pycache__/__init__.cpython-311.pyc b/core/migrations/__pycache__/__init__.cpython-311.pyc index 9c833c8..5fe63f4 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..f66a94e 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,32 @@ from django.db import models +from django.utils import timezone -# Create your models here. +class Category(models.Model): + TRANSACTION_TYPES = [ + ('income', 'Income'), + ('expense', 'Expense'), + ] + name = models.CharField(max_length=100) + type = models.CharField(max_length=10, choices=TRANSACTION_TYPES, default='expense') + icon = models.CharField(max_length=50, blank=True, null=True, help_text="FontAwesome icon name (e.g., fa-utensils)") + + class Meta: + verbose_name_plural = "Categories" + + def __str__(self): + return f"{self.name} ({self.get_type_display()})" + +class Transaction(models.Model): + TYPES = [ + ('income', 'Income'), + ('expense', 'Expense'), + ] + amount = models.DecimalField(max_digits=10, decimal_places=2) + category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True, related_name='transactions') + date = models.DateField(default=timezone.now) + description = models.CharField(max_length=255, blank=True) + type = models.CharField(max_length=10, choices=TYPES, default='expense') + created_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"{self.get_type_display()}: {self.amount} - {self.description[:20]}" \ No newline at end of file diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..b4cdc37 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,25 +1,72 @@ -
- -