Opened 9 years ago
Last modified 8 years ago
#27982 closed Bug
Possible race condition related to queryset union — at Initial Version
| 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
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
I've also attached a video showing the results while using different breakpoints.