Añadidas tandas: 4, 4b y 7 #33
@ -5,15 +5,34 @@
|
|||||||
|
|
||||||
<a class="btn" href="{% url 'tag_create' %}">➕ Nueva etiqueta</a>
|
<a class="btn" href="{% url 'tag_create' %}">➕ Nueva etiqueta</a>
|
||||||
|
|
||||||
<ul>
|
<div class="table-wrap">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Gastos</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
<li class="table-actions">
|
<tr>
|
||||||
{{ tag.name }}
|
<td>{{ tag.name }}</td>
|
||||||
|
<td>{{ tag.expense_count }}</td>
|
||||||
|
<td class="table-actions">
|
||||||
<a href="{% url 'tag_edit' tag.id %}">Editar</a>
|
<a href="{% url 'tag_edit' tag.id %}">Editar</a>
|
||||||
<a href="{% url 'tag_delete' tag.id %}" class="danger">Eliminar</a>
|
<a href="{% url 'tag_delete' tag.id %}" class="danger">Eliminar</a>
|
||||||
</li>
|
</td>
|
||||||
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<li>No hay etiquetas</li>
|
<tr>
|
||||||
|
<td colspan="3" class="empty-state">
|
||||||
|
<p>No hay etiquetas</p>
|
||||||
|
<a href="{% url 'tag_create' %}">Añade la primera</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
23
expenses_manager/expenses/tests/test_tags.py
Normal file
23
expenses_manager/expenses/tests/test_tags.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import pytest
|
||||||
|
from datetime import date
|
||||||
|
from decimal import Decimal
|
||||||
|
from django.urls import reverse
|
||||||
|
from expenses.models import Expense, Tag
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def test_tag_list_annotates_expense_usage_count(auth_client, user, account, category):
|
||||||
|
used = Tag.objects.create(owner=user, name="Usada")
|
||||||
|
unused = Tag.objects.create(owner=user, name="Sin usar")
|
||||||
|
|
||||||
|
for _ in range(2):
|
||||||
|
expense = Expense.objects.create(
|
||||||
|
owner=user, account=account, category=category, amount=Decimal("10"), date=date.today()
|
||||||
|
)
|
||||||
|
expense.tags.add(used)
|
||||||
|
|
||||||
|
response = auth_client.get(reverse('tag_list'))
|
||||||
|
|
||||||
|
counts = {tag.name: tag.expense_count for tag in response.context["tags"]}
|
||||||
|
assert counts == {"Usada": 2, "Sin usar": 0}
|
||||||
@ -15,7 +15,7 @@ from .forms import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.db.models import Sum, ProtectedError
|
from django.db.models import Sum, Count, ProtectedError
|
||||||
from django.db.models.functions import ExtractMonth, ExtractYear, ExtractDay
|
from django.db.models.functions import ExtractMonth, ExtractYear, ExtractDay
|
||||||
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
@ -635,7 +635,11 @@ def dashboard(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def tag_list(request):
|
def tag_list(request):
|
||||||
tags = Tag.objects.filter(owner=request.user)
|
tags = (
|
||||||
|
Tag.objects.filter(owner=request.user)
|
||||||
|
.annotate(expense_count=Count("expenses"))
|
||||||
|
.order_by("name")
|
||||||
|
)
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request, "expenses/tag_list.html", {"active_menu": "settings", "tags": tags}
|
request, "expenses/tag_list.html", {"active_menu": "settings", "tags": tags}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user