Opened 8 years ago
Last modified 7 years ago
#27982 closed Bug
Possible race condition related to queryset union — at Version 1
Reported by: | gigelu | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.11 |
Severity: | Normal | Keywords: | |
Cc: | Florian Apolloner | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I found a strange bug: the results from a paginator are affected randomly by setting breakpoints in the IDE.
The bug appears only when I am using union
on a queryset.
I am using Django 1.11rc1 with DRF 3.6.2.
The models:
class BaseNotification(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) type = models.CharField(max_length=10, choices=TYPES, default=TYPE_SIMPLE, blank=True) popup_type = models.CharField(max_length=10, choices=POPUP_TYPES, default=POPUP_DEFAULT) title = models.CharField(max_length=200, blank=True) message = models.TextField() completed = models.BooleanField(blank=True, default=False) date_completed = models.DateTimeField(null=True, blank=True, default=None) date_created = models.DateTimeField(auto_now_add=True) class SimpleNotification(BaseNotification): def save(self, *args, **kwargs): self.type = self.TYPE_SIMPLE super().save(*args, **kwargs) class DecisionNotification(BaseNotification): ... (not relevant)
The view:
class NotificationView(ListAPIView): permission_classes = [IsAuthenticated] filter_backends = [OrderingFilter] ordering_fields = ['completed', 'date_created', 'type'] ordering = ['-completed', '-date_created'] serializer_class = NotificationSerializer def get_queryset(self): qs1 = SimpleNotification.objects.filter(user=self.request.user).only( 'type', 'popup_type', 'completed', 'date_created') qs2 = DecisionNotification.objects.filter(user=self.request.user).only( 'type', 'popup_type', 'completed', 'date_created') qs = qs1.union(qs2) return qs
The serializer:
class NotificationSerializer(serializers.ModelSerializer): title = serializers.CharField(source='the_title') class Meta: model = SimpleNotification fields = ['type', 'popup_type', 'title', 'url', 'completed', 'date_created']
The problem: I have 5 notifications in DB (3 simple, 2 decision), but it returns only the first one in normal usage, and sometimes all or sometimes one when I am using breakpoints.
I've isolated the problem near this line of code: https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/pagination.py#L208. If I put a breakpoint inside the paginator's init (https://github.com/django/django/blob/master/django/core/paginator.py#L29) I get the correct result every time.
http://i.imgur.com/9zoikMQ.png
http://i.imgur.com/bsHgxig.png