Ich benutze Django 1.7.7.Doppelte Elemente in Django Paginate nach `order_by` Aufruf
Ich frage mich, ob jemand das erlebt hat. Dies ist meine Frage:
events = Event.objects.filter(
Q(date__gt=my_date) | Q(date__isnull=True)
).filter(type__in=[...]).order_by('date')
Wenn ich versuche, dann Paginieren sie
p = Paginator(events, 10)
p.count # Gives 91
event_ids = []
for i in xrange(1, p.count/10 + 2):
event_ids += [i.id for i in p.page(i)]
print len(event_ids) # Still 91
print len(set(event_ids)) # 75
Ich bemerkte, dass, wenn ich die .order_by
entfernt, ich habe keine Duplikate erhalten. Ich versuchte dann nur .order_by
mit Event.objects.all().order_by('date')
, die keine Duplikate gab.
Schließlich habe ich versucht, dieses:
events = Event.objects.filter(
Q(date__gt=my_date) | Q(date__isnull=True)
).order_by('date')
p = Paginator(events, 10)
events.count() # Gives 131
p.count # Gives 131
event_ids = []
for i in xrange(1, p.count/10 + 2):
event_ids += [i.id for i in p.page(i)]
len(event_ids) # Gives 131
len(set(event_ids)) # Gives 118
... und es gibt Duplikate. Kann mir jemand erklären, was vor sich geht?
Ich grub in die Django-Quelle (https://github.com/django/django/blob/master/django/core/paginator.py#L46-L55) und es scheint etwas damit zu tun zu haben, wie Django die object_list
schneidet.
Jede Hilfe wird geschätzt. Vielen Dank.
Edit: distinct()
hat keinen Einfluss auf die Duplikate. Es gibt keine Duplikate in der Datenbank und ich glaube nicht, dass die Abfrage irgendwelche Duplikate einführt ([e for e in events.iterator()]
erzeugt keine Duplikate). Es ist nur, wenn der Paginator schneidet.
Edit2: Hier ist ein vollständigeres Beispiel
In [1]: from django.core.paginator import Paginator
In [2]: from datetime import datetime, timedelta
In [3]: my_date = timezone.now()
In [4]: 1 events = Event.objects.filter(
2 Q(date__gt=my_date) | Q(date__isnull=True)
3).order_by('date')
In [5]: events.count()
Out[5]: 134
In [6]: p = Paginator(events, 10)
In [7]: p.count
Out[7]: 134
In [8]: event_ids = []
In [9]: 1 for i in xrange(1, p.num_pages + 1):
2 event_ids += [j.id for j in p.page(i)]
In [10]: len(event_ids)
Out[10]: 134
In [11]: len(set(event_ids))
Out[11]: 115
Haben Sie versucht [distinct()] (https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.distinct) Methode? – Gocht
Nein, ich habe nicht, aber ich denke nicht, dass distinct helfen würde. Die Ergebnisse aus dem Abfrage-Set werden nicht dupliziert. Ich denke, es ist die Art, wie sie aus dem Queryset herausgezogen werden (d. H. Schneiden). Running 'len (set ([i.id für i in Ereignissen])) == events.count()' ergibt 'True'. – truetuna
Ich konnte den Punkt Ihrer for-Schleife nicht verstehen. Kannst du nicht 'event_ids = [i.id für i in Ereignissen]' 'verwenden? – malisit