3

だから私は次のクエリを持っています:

Person.objects.annotate(film_count=Count('film')).filter(film_count__gte=3).order_by('?')[0]

これは、3 つ以上のフィルムを持っているランダムな人物を引き出します。ただし、django のドキュメント ( https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by-fields ) に記載されているように、('?') を使用したこのアプローチは非常に遅く、このクエリがユーザーによって頻繁に使用されるように計画してください。

それを行う1つの方法は、そのクエリの完全なリストによって生成されたすべての主キーを取得し、それをtxtファイルに保存して、毎回ランダムに選択することだと思います. しかし、もっとエレガントな解決策があるかどうか疑問に思っていますか?

別の方法は次のようにすることだと思います:

Person.objects.annotate(film_count=Count('film')).filter(film_count__gte=3).get(pk=randint(1,num_persons))

ここで、num_persons はデータベース内の人数です。その人物がクエリと一致せず、DoesNotExistエラーがスローされた場合は、単純にもう一度実行します。

4

3 に答える 3

1

最も簡単な解決策を使用できます。行を数えて、ランダムに 1 つ選択します。

queryset = Person.objects.annotate(film_count=Count('film')).filter(film_count__gte=3)
count = queryset.count()
result = queryset[random.randint(count)]

ただし、スニペットの 2 行目と 3 行目より前に一部の行が削除された場合、このアプローチは失敗する可能性があることに注意してください (したがって、最後の行を再試行で try-catch にラップする可能性があります)。

于 2013-10-19T17:12:37.923 に答える
0

ORMでランダム演算子を指定すると、2つの異なるランダム結果が得られると確信していますね。

MyModel.objects.order_by('?')[:2] # 2 random results.

Note: order_by('?') queries may be expensive and slow, depending on the database backend you’re using.
于 2014-01-24T06:15:18.100 に答える
0

投稿で編集したように、次のことができます。

Person.objects.annotate(film_count=Count('film')).filter(film_count__gte=3).get(pk=randint(1,num_persons))

try/except ブロック内で、レコードが存在しない場合は、別の乱数で再試行してください。

于 2013-10-19T10:42:28.603 に答える