2012-02-19 35 views

Respuesta

16

Seleccionar un elemento aleatorio de una lista de todos los objetos de la base de datos no es una solución goog, ya que recuperar todos los elementos de la base de datos puede tener un gran impacto en el rendimiento, como tampoco se usa .

La mejor solución debe ser para recuperar un elemento con un índice de azar:

import random 

random_idx = random.randint(0, Model.objects.count() - 1) 
random_obj = Model.objects.all()[random_idx] 
+0

¿Crees que Model.objects.all() es costoso? Verme la respuesta editada. –

+0

¿Tiene una explicación/punto de referencia que muestre que esto es más rápido que order_by ('?') [0]? Sé lo que dicen los documentos, pero la clave aquí es que el DB seleccionará solo 1 ítem y la velocidad sería efectivamente la misma (dado un motor razonablemente inteligente de DB). order_by ('?') sería realmente lento solo si realmente está buscando más de una fila ... – Delyan

+0

@AamirAdnan: Por supuesto, el costo dependerá de su número de registros y es posible que funcione bien con unos pocos registros, pero también si usas 'values_list' y digamos millones de registros, django necesitará obtener el' id' de cada objeto. –

2

La solución de Aamir seleccionará todos los objetos antes de descartar todos menos uno. Esto es extremadamente inútil y, además, este tipo de cálculo debe hacerse en la base de datos.

model.objects.all().order_by('?')[0] 

Leer más aquí: https://docs.djangoproject.com/en/dev/ref/models/querysets/#order-by

Editar: La respuesta de lazerscience es de hecho más rápido, como se muestra here.

+3

Esto también es bastante lento, como se puede leer en el enlace que ya ha proporcionado: 'Nota: order_by ('?') Consultas pueden ser costoso y lento ...' Don –

0

lo haría un poco diferente. Los querysets son perezosos de todos modos en django.

import random 

def get_my_random_object(): 
    object = random.choice(model.objects.all()) 
    return object 

https://docs.djangoproject.com/en/dev/topics/db/queries/#querysets-are-lazy https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated

+4

'random.choice()' llama a 'len (queryset)' (como se ve en ['random.py'] (https://hg.python.org/cpython/file/3985104e2290/Lib/random.py#l253)). Esto evaluará el queryset completo y lo extraerá a la memoria antes de elegir un solo elemento. – knbk

Cuestiones relacionadas