Skip to content

Commit 8645cea

Browse files
apps/kiezradar: fix race condition with kiez creation (#6587)
1 parent 5942313 commit 8645cea

2 files changed

Lines changed: 32 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ This project (not yet) adheres to [Semantic Versioning](https://semver.org/spec/
2929

3030
- Kiezradar filter projects by organisation
3131
- Kiezradar show projects/plans with the same name in Projects List
32+
- Kiezradar kiez creation race condition prevented
3233
- Accessibility improvements regarding alternative texts
3334
- Accessibility improvements regarding semantic structure and adaptability
3435
- Accessibility improvements regarding structured navigation and consistent focus indication

meinberlin/apps/kiezradar/api.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
from django.db import transaction
2+
from rest_framework import status
13
from rest_framework import viewsets
4+
from rest_framework.exceptions import ValidationError
5+
from rest_framework.response import Response
26

37
from adhocracy4.api.permissions import ViewSetRulesPermission
48

@@ -17,11 +21,33 @@ class KiezRadarViewSet(viewsets.ModelViewSet):
1721
serializer_class = KiezRadarSerializer
1822
permission_classes = [ViewSetRulesPermission]
1923

20-
def perform_create(self, serializer):
21-
"""
22-
Override to save the user from the request.
23-
"""
24-
serializer.save(creator=self.request.user)
24+
def create(self, request, *args, **kwargs):
25+
user = request.user
26+
27+
with transaction.atomic():
28+
from django.contrib.auth import get_user_model
29+
30+
User = get_user_model()
31+
32+
locked_user = User.objects.select_for_update().get(id=user.id)
33+
34+
current_count = KiezRadar.objects.filter(creator=locked_user).count()
35+
36+
if current_count >= KiezRadar.KIEZRADAR_LIMIT:
37+
raise ValidationError(
38+
detail={
39+
"error": f"Users can only have up to {KiezRadar.KIEZRADAR_LIMIT} kiezradar filters."
40+
}
41+
)
42+
43+
# Create serializer WITHOUT the validation check (or with safe version)
44+
serializer = self.get_serializer(data=request.data)
45+
serializer.is_valid(raise_exception=True)
46+
47+
instance = serializer.save(creator=locked_user)
48+
49+
response_serializer = self.get_serializer(instance)
50+
return Response(response_serializer.data, status=status.HTTP_201_CREATED)
2551

2652
def get_permission_object(self):
2753
return None

0 commit comments

Comments
 (0)