44 lines
1.6 KiB
Python
44 lines
1.6 KiB
Python
from django.db.models.signals import post_save, post_delete
|
|
from django.dispatch import receiver
|
|
from channels.layers import get_channel_layer
|
|
from asgiref.sync import async_to_sync
|
|
from django.template.loader import render_to_string
|
|
from .models import Expense
|
|
|
|
@receiver(post_save, sender=Expense)
|
|
def expense_saved(sender, instance, created, **kwargs):
|
|
channel_layer = get_channel_layer()
|
|
|
|
# Renderizamos la fila parcial
|
|
html = render_to_string('expenses/partials/expense_row.html', {'expense': instance})
|
|
|
|
# Envolvemos el HTML con las directivas OOB (Out-of-Band) de HTMX
|
|
if created:
|
|
# Si es nuevo, lo insertamos al principio del tbody con id "expenses-tbody"
|
|
payload = f'<tbody id="expenses-tbody" hx-swap-oob="afterbegin">{html}</tbody>'
|
|
else:
|
|
# Si ya existe, HTMX reemplazará automáticamente el tr con el mismo ID si usamos hx-swap-oob="true"
|
|
payload = html.replace('<tr ', '<tr hx-swap-oob="true" ')
|
|
|
|
async_to_sync(channel_layer.group_send)(
|
|
'expenses_updates',
|
|
{
|
|
'type': 'expense_update',
|
|
'html': payload
|
|
}
|
|
)
|
|
|
|
@receiver(post_delete, sender=Expense)
|
|
def expense_deleted(sender, instance, **kwargs):
|
|
channel_layer = get_channel_layer()
|
|
# Para borrar, mandamos un elemento vacío con swap out-of-band que reemplace la fila eliminada
|
|
payload = f'<tr id="expense-{instance.id}" hx-swap-oob="outerHTML"></tr>'
|
|
|
|
async_to_sync(channel_layer.group_send)(
|
|
'expenses_updates',
|
|
{
|
|
'type': 'expense_update',
|
|
'html': payload
|
|
}
|
|
)
|