diff --git a/server/broadcast/api_views.py b/server/broadcast/api_views.py index 891f397..26d84b2 100644 --- a/server/broadcast/api_views.py +++ b/server/broadcast/api_views.py @@ -2,6 +2,7 @@ from rest_framework.decorators import action, api_view, permission_classes from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated, AllowAny +from django.db import transaction from .models import BroadcastMessage from .serializers import BroadcastMessageSerializer from dashboard.models import UserDetails @@ -46,8 +47,16 @@ def set_active(self, request, pk=None): if message.user != request.user and not request.user.is_staff: return Response({'error': 'Permission denied'}, status=status.HTTP_403_FORBIDDEN) - message.active = True - message.save() + with transaction.atomic(): + message = BroadcastMessage.objects.select_for_update().get(pk=pk) + + BroadcastMessage.objects.select_for_update().filter( + user=message.user, active=True + ).update(active=False) + + message.active = True + message.save() + return Response({'message': 'Message set as active'}) @@ -57,13 +66,11 @@ def get_user_broadcast(request, user_slug): try: user_details = UserDetails.objects.select_related('user').get(_slug=user_slug) - # Get active broadcast message if exists active_message = BroadcastMessage.objects.filter( user=user_details.user, active=True ).first() - # Build response with user details and active message response_data = { 'username': user_details.user.username, 'user_username': user_details.user.username, diff --git a/server/broadcast/models.py b/server/broadcast/models.py index 0b5a1ee..24d36cb 100644 --- a/server/broadcast/models.py +++ b/server/broadcast/models.py @@ -1,8 +1,7 @@ -from django.db import models +from django.db import models, transaction from django.conf import settings -# Create your models here. class BroadcastMessage(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='messages') message = models.TextField() @@ -10,8 +9,15 @@ class BroadcastMessage(models.Model): def save(self, *args, **kwargs): if self.active: - BroadcastMessage.objects.filter(user=self.user, active=True).update(active=False) - super().save(*args, **kwargs) + with transaction.atomic(): + + BroadcastMessage.objects.select_for_update().filter( + user=self.user + ).update(active=False) + # Save this message as active + super().save(*args, **kwargs) + else: + super().save(*args, **kwargs) def __str__(self): return f'{self.user.username}: {self.message[:20]}' \ No newline at end of file