2009-07-16 8 views
7

Estoy tratando de obtener una foto al azar de cada álbum de los datos creados por syncr. El modelo (abreviado) se ve así:Django - Seleccione una foto al azar de cada álbum


class Album(models.Model): 
    title = models.CharField(max_length=200) 
    photos = models.ManyToManyField('Photo') 

class Photo(models.Model): 
    title = models.CharField(max_length=200) 

He intentado muchos enfoques diferentes sin éxito. ¿Es este otro fácil?

Tome 2: código final:

galerías def (solicitud, template_name = 'galleries.html'):

albums = Album.objects.select_related().all() 
album_list = [] 
for album in albums: 
    album_list.append({'title':album.title, 'id':album.id, 'photo':album.random_photo()}) 

return render_to_response(template_name, { 
    "album_list": album_list, 
}) 
+0

aprendido mucho de todas estas respuestas y, finalmente, utiliza una combinación. Muchas gracias a todas: galerías def (solicitud, TEMPLATE_NAME = 'galleries.html'): álbumes = Album.objects.select_related (todos)() album_list = [] para el álbum en álbumes:. album_list. append ({ 'título': album.title, 'id': album.id, 'foto': album.random_photo()}) retorno render_to_response (template_name, { "album_list": album_list, }) – PhoebeB

Respuesta

8

No he probado el código, pero este es el idea correcta, y la select_related debe ayudarle de incurrir demasiaaaado muchas consultas db ...

from models import Album, Photo 
import random 

def get_random(): 
    albums = Album.objects.select_related().all() 
    randpics = [] 
    for album in albums: 
     total = album.photos.count() 
     photo = album.photos.get(pk=random.randrange(0,total)) 
     randpics.append(photo) 
    return randpics 
+0

Necesita hacer algo ligeramente diferente en el medio ya que supone que todas las fotos tienen claves principales en el rango de 0 a total. ¿Puedo obtener un elemento aleatorio de una lista de todos album.photos? – PhoebeB

+0

http://elpenia.wordpress.com/2010/05/11/getting-random-objects-from-a-queryset-in-django/ – andrewrk

4
randomPhotos = [random.choice(album.photos.objects.all()) for album in album.objects.all()] 
+0

oooh , lista de comprensión, lindo! –

+0

para álbum en Album.objects.all() –

+0

Probé esto: >>> import random >>> randomPhotos = [random.choice (album.photos.objects.todos()) para el álbum en Album.objects.all()] y consiguió esto: Rastreo (llamada más reciente pasado): Archivo "", línea 1, en? AttributeError: el objeto 'ManyRelatedManager' no tiene ningún atributo 'objetos' >>> – PhoebeB

3

Si comete un método personalizado en su modelo del álbum, que se ve algo como esto:

def random_photo(self): 
    import random 
    return random.choice(self.photos.all()) 

que devolverá una foto al azar de la instancia actual del álbum es decir

albumObj.random_photo() 

Nota: el código no probado

24

, usted puede obtener un único objeto aleatorio de cualquier Queryset utilizando el método order_by con un signo de interrogación como argumento. Esto puede ser mejor que llamar a Photo.objects.all() porque solo devolverá un objeto de fotografía por consulta de la base de datos, en lugar del conjunto completo y luego usará python para filtrar la lista.

Por ejemplo, esta consulta devolverá una sola foto al azar:

Photo.objects.order_by('?')[:1]

La siguiente no es óptima, ya que necesita 1 consulta para cada álbum, pero funcionaría:

photos = [] 
for a in Album.objects.all(): 
    photo = a.photos.order_by('?')[:1] 
    photos.append(photo) 

Editar: Cambió el índice [0] a porque el primero generará un error IndexError si el álbum no contiene fotos.

Por otra parte, en la lista de la sintaxis de la comprensión:

photos = [a.photos.order_by('?')[:1] for a in Album.objects.all()] 
+2

+1: parece que esta es una buena manera de hacerlo, y si ¡Podría darte otro +1 por enseñarme algo sobre el orden por lo que no sabía! ¡Gracias! – SingleNegationElimination

+0

+1 para el conocimiento de order_by también. – Harold

+0

, consulte http://buffis.com/2008/01/20/how-to-get-random-rows-from-mysql-using-django/comment-page-1/ – chefsmart

Cuestiones relacionadas