Exactamente, ¿qué tan aleatorio deben ser? ¿Tiene que ser diferente para cada usuario, o es simplemente la apariencia de la aleatoriedad que es importante?
Si es el último, entonces simplemente puede agregar un campo llamado ordering
al modelo en cuestión, y rellenarlo con enteros aleatorios. De lo contrario, a menos que el conjunto de registros sea pequeño (y, dado que está siendo paginado, lo dudo), almacenar un conjunto de consulta aleatorio para cada sesión podría convertirse en un problema de memoria muy rápidamente a menos que sepa que la base de usuarios es muy pequeña. Aquí es una posible solución que imita aleatoriedad pero en realidad sólo crea 5 juegos al azar:
import random
from django.core import cache
RANDOM_EXPERIENCES=5
def my_view(request):
if not request.session.get('random_exp'):
request.session['random_exp']=random.randrange(0,RANDOM_EXPERIENCES)
object_list = cache.get('random_exp_%d' % request.session['random_exp'])
if not object_list:
object_list = list(Object.objects.all().order_by('?'))
cache.set('random_exp_%d' % request.session['random_exp'], object_list, 100)
paginator = Paginator(object_list, 10)
page = 1 # or whatever page we have
display_list = paginator.page(page)
....
En este ejemplo, en lugar de crear una queryset independiente para cada usuario (que resulta en potencialmente miles de QuerySets en el almacenamiento) y almacenarla en request.session (un mecanismo de almacenamiento menos eficiente que el caché, que puede configurarse para usar algo muy eficiente, como memcached), ahora solo tenemos 5 querysets almacenados en el caché, pero con suerte una experiencia suficientemente aleatoria para la mayoría de los usuarios. Si quieres más aleatoriedad, aumentar el valor de RANDOM_EXPERIENCES debería ser útil. Creo que probablemente puedas subir hasta 100 con pocos problemas de rendimiento.
Si los registros propios cambian con poca frecuencia, puede establecer un tiempo de espera extremadamente alta para la memoria caché.
actualización
Aquí está una manera de ponerlo en práctica que utiliza poco más de memoria/almacenamiento, pero se asegura de que cada usuario puede "aferrarse" a su queryset sin peligro de su tiempo caché a cabo (suponiendo que 3 horas es lo suficientemente largo para mirar los registros).
import datetime
...
if not request.session.get('random_exp'):
request.session['random_exp']="%d_%d" % (
datetime.datetime.strftime(datetime.datetime.now(),'%Y%m%dH'),
random.randrange(0, RANDOM_EXPERIENCES)
)
object_list = cache.get("random_exp_%s" % request.session['random_exp'])
if not object_list:
object_list = list(Object.objects.all().order_by('?'))
cache.set(cache_key, "random_exp_%s" % request.session['random_exp'], 60*60*4)
Aquí creamos un conjunto de consultas en caché que no excede el tiempo de espera durante 4 horas. Sin embargo, la clave request.session se establece en el año, el mes, el día y la hora para que alguien que ingrese vea un juego de registros actual para esa hora. Cualquier persona que ya haya visto el conjunto de consulta podrá verlo durante al menos otras 3 horas (o mientras su sesión esté activa) antes de que caduque. Como máximo, habrá 5 * conjuntos de consultas RANDOM_EXPERIENCES almacenados en caché.
nice one - no se usó el caché como antes - solo para vistas de caché. parece tener sentido Y tienes razón: la aleatoriedad es solo por las apariencias, no es verdaderamente aleatoria. Gracias. –