myqueryset = Content.objects.filter(random 100)
Antwort
Content.objects.all().order_by('?')[:100]
Siehe order_by docs. Beachten Sie auch, dass dieser Ansatz nicht gut skaliert (tatsächlich skaliert er wirklich sehr schlecht). Siehe this SO answer für eine bessere Möglichkeit zur zufälligen Auswahl, wenn Sie große Datenmengen haben.
Wenn Sie dies mehr als einmal tun, müssen Sie dies in Ihrer Datenbank entwerfen.
Wenn Sie es einmal tun, können Sie es sich leisten, die saftige Strafe zu bezahlen. Dies bringt Sie genau 100 mit wirklich guten zufälligen Eigenschaften. Es benötigt jedoch viel Speicher.
pool= list(Content.objects.all())
random.shuffle(pool)
object_list = pool[:100]
Hier ist ein weiterer Algorithmus, der auch langsam ist, da er die gesamte Tabelle durchsuchen kann. Es ist nicht sehr viel Speicher überhaupt verwenden und es kann nicht genau 100.
total_count= Content.objects.count()
fraction = 100./total_count
object_list = [ c for c in Content.objects.all() if random.random() < fraction ]
bekommen Wenn Sie mehr als einmal tun wollen, müssen Sie ein Attribut hinzufügen, zum Inhalt für „random effektive Filterung zu ermöglichen "Werte. Zum Beispiel könnten Sie dies tun.
class Content(models.Model):
... etc. ...
def subset(self):
return self.id % 32768
Dies wird Ihre Daten in 32768 verschiedene Untergruppen partitionieren. Jede Teilmenge ist 1/32768'th Ihrer Daten. Um 100 zufällige Elemente zu erhalten, benötigen Sie 100 * 32768/total_count-Teilmengen Ihrer Daten.
total_count = Content.objects.count()
no_of_subsets= 100*32768/total_count
object_list = Content.objects.filter(subset__lte=no_of_subsets)
Dies ist schnell und es ist reproduzierbar. Die Teilmengen sind "willkürlich", nicht technisch "zufällig".
Guter Punkt für die Leistung –
Ich mag Ihren letzten Ansatz, obwohl ich glaube nicht, dass Sie auf Eigenschaften filtern können. Sie müssten die Teilmengenspalte im Modell selbst hinzufügen und ihren Wert wie folgt auf Speichern setzen: http://ifacethoughts.net/2009/07/14/calculated-fields-in-django/ – jesal
Teilmenge als Methode hinzufügen Das Content-Modell reicht nicht aus, um es zu filtern, wie es in Ihrem letzten Snippet vorgeschlagen wurde. –
ich tun:
import random
object_list = list(Content.objects.filter(foo=bar).values()[:100])
random.shuffle(object_list)
Läuft nur Einzel einfache MySQL-Abfrage und ist auf die Leistung gut.
Dies liefert keine zufälligen Datensätze aus der Datenbank. Es nimmt die ersten hundert Aufnahmen und mischt sie. Datensätze ab 101 haben keine Chance, ausgewählt zu werden. – Blair
Ich wollte die Verwendung der Shuffle-Funktion über order_by ('?') Vorschlagen, die schwerwiegende Leistungsprobleme hat: http://stackoverflow.com/a/6405601/232649 Zum Mischen aller Datensätze: shuffle (Liste (Content.objects .all())) [: 100] – Pratyush
Und die all() ist redundant, aber ich erinnere mich nie daran. – Tom
Das ist großartig! Durch das Debugging habe ich festgestellt, dass es sogar eine gute Abfrage generiert, die nur 20 Elemente mit einer Abfrage erfasst und ORDER BY RAND() für zufällige Abfragen verwendet. Guter Gott, das ist fantastisch. –