Django ORM | Выборка рандомных записей?

Есть задача: выбрать в подборку статей 3 рандомные записи, которые не должны повторяться между собой. Да, статей немного, модели статей легковесны. Я мог бы реализовать следующие варианты и не париться:

1) С помощью random.choice() и list.remove()

    # Генерируем рандомную подборку статей.
    all_articles = list(Article.objects.all())
    set_size = 3 if len(all_articles) > 3 else len(all_articles)
    articles_set = []
    for _ in range(set_size):
        random_article = random.choice(all_articles)
        all_articles.remove(random_article)
        articles_set.append(random_article)
    articles_set = QuerySet(articles_set)

Этот вариант мне не нравится, т.к. нужно подгружать на сервер ВСЕ записи. А если их будет очень много? Задача такая тривиальная...

2) Используя ленивость QuerySet

    all_articles = Article.objects.all()
    count_articles = all_articles.count()

    random_indexes = list(range(count_articles))
    random.shuffle(random_indexes)

    set_size = 3 if count_articles > 3 else count_articles
    articles_set = QuerySet([all_articles[random_indexes[i]]
                             for i in range(set_size)])

Здесь мне не нравится две вещи:

  • приходится создавать список размером кол-ва записей в БД (это лучше, т.к. теперь мы храним хотя бы не модели);
  • т.к. QuerySet ленивый, то __ getitem __ у него посылает отдельные запросы к нужным записям в БД.

В общем, прошу вашей помощи. Задача такая тривиальная, но я не могу додуматься, как же ее все-таки решить идеально. Хотелось бы получить 3 рандомные неповторяющиеся записи из БД одним запросом.

Вернуться на верх