From d0eeaa2c1821f16cb06571e96dd384e44ebe6428 Mon Sep 17 00:00:00 2001 From: JKuijperM Date: Thu, 8 Jan 2026 11:53:16 +0100 Subject: [PATCH] Created the models and its test --- expenses_manager/expenses/admin.py | 6 +- .../expenses/migrations/0001_initial.py | 65 ++++++++++++++ expenses_manager/expenses/models.py | 88 ++++++++++++++++++- .../expenses/tests/test_models.py | 26 ++++++ 4 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 expenses_manager/expenses/migrations/0001_initial.py create mode 100644 expenses_manager/expenses/tests/test_models.py diff --git a/expenses_manager/expenses/admin.py b/expenses_manager/expenses/admin.py index 8c38f3f..26b0d26 100644 --- a/expenses_manager/expenses/admin.py +++ b/expenses_manager/expenses/admin.py @@ -1,3 +1,7 @@ from django.contrib import admin +from .models import Category, Account, Tag, Expense -# Register your models here. +admin.site.register(Category) +admin.site.register(Account) +admin.site.register(Tag) +admin.site.register(Expense) \ No newline at end of file diff --git a/expenses_manager/expenses/migrations/0001_initial.py b/expenses_manager/expenses/migrations/0001_initial.py new file mode 100644 index 0000000..8a3b912 --- /dev/null +++ b/expenses_manager/expenses/migrations/0001_initial.py @@ -0,0 +1,65 @@ +# Generated by Django 5.2.10 on 2026-01-07 22:49 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Account', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=100)), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='accounts', to=settings.AUTH_USER_MODEL)), + ], + ), + 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)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='expenses.category')), + ], + options={ + 'verbose_name_plural': 'categories', + 'unique_together': {('name', 'parent')}, + }, + ), + migrations.CreateModel( + name='Tag', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50)), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tags', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'unique_together': {('name', 'owner')}, + }, + ), + migrations.CreateModel( + name='Expense', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('amount', models.DecimalField(decimal_places=2, max_digits=10)), + ('description', models.TextField(blank=True)), + ('created_at', models.DateField(auto_now_add=True)), + ('account', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expenses', to='expenses.account')), + ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='expenses', to='expenses.category')), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='expenses', to=settings.AUTH_USER_MODEL)), + ('tags', models.ManyToManyField(blank=True, related_name='expenses', to='expenses.tag')), + ], + options={ + 'ordering': ['-date'], + }, + ), + ] diff --git a/expenses_manager/expenses/models.py b/expenses_manager/expenses/models.py index 71a8362..6e3f82b 100644 --- a/expenses_manager/expenses/models.py +++ b/expenses_manager/expenses/models.py @@ -1,3 +1,89 @@ from django.db import models +from django.conf import settings +from django.db.models.fields import related -# Create your models here. +class Category(models.Model): + name = models.CharField(max_length=100) + parent = models.ForeignKey( + "self", + on_delete=models.CASCADE, + null=True, + blank=True, + related_name="children", + ) + + class Meta: + unique_together = ("name", "parent") + verbose_name_plural = "categories" + + def __str__(self): + return self.name + + +class Account(models.Model): + name = models.CharField(max_length=100) + owner = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="accounts", + ) + + def __str__(self): + return self.name + + +class Tag(models.Model): + name = models.CharField(max_length=50) + owner = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="tags", + ) + + class Meta: + unique_together = ("name", "owner") + + def __str__(self): + return self.name + + +class Expense(models.Model): + date = models.DateField() + amount = models.DecimalField(max_digits=10, decimal_places=2) + description = models.TextField(blank=True) + + owner = models.ForeignKey( + settings.AUTH_USER_MODEL, + on_delete=models.CASCADE, + related_name="expenses", + ) + + category = models.ForeignKey( + Category, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="expenses", + ) + + account = models.ForeignKey( + Account, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="expenses", + ) + + tags = models.ManyToManyField( + Tag, + blank=True, + related_name="expenses", + ) + + created_at = models.DateField(auto_now_add=True) + + class Meta: + ordering = ["-date"] + + def __str__(self): + return "{} - {}".format(self.date, self.amount) \ No newline at end of file diff --git a/expenses_manager/expenses/tests/test_models.py b/expenses_manager/expenses/tests/test_models.py new file mode 100644 index 0000000..8c31d43 --- /dev/null +++ b/expenses_manager/expenses/tests/test_models.py @@ -0,0 +1,26 @@ +import pytest +from django.contrib.auth.models import User +from expenses.models import Category, Account, Expense + +@pytest.mark.django_db +def test_create_basic_expense(): + user = User.objects.create_user( + username="testuser", + password="password", + ) + + category = Category.objects.create(name="Comida") + account = Account.objects.create(name="Cuenta principal", owner=user) + + expense = Expense.objects.create( + date="2024-01-01", + amount=25.50, + owner=user, + category=category, + account=account + ) + + assert expense.amount == 25.50 + assert expense.category.name == "Comida" + assert expense.owner.username == "testuser" +