Am trying to get a random photo from each album from the data created by syncr. The model (abbreviated) looks like this:
class Album(models.Model):
title = models.CharField(max_length=200)
photos = models.ManyToManyField('Photo')
class Photo(models.Model):
title = models.CharField(max_length=200)
I've tried lots of different approaches with no success. Is this another easy one?
Take 2: Final code:
def galleries(request, 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,
})
You can get a single random object from any Queryset using the order_by
method with a question mark as an argument. This may be better than calling Photo.objects.all() because it will only return one photo object per query from the database, rather than the whole set and then using python to filter the list.
For instance, this query will return a single random photo:
Photo.objects.order_by('?')[:1]
The following is not optimal, because it needs 1 query for each album, but it would work:
photos = []
for a in Album.objects.all():
photo = a.photos.order_by('?')[:1]
photos.append(photo)
Edit:
Changed the [0]
index to [:1]
because the former will raise an IndexError if the albumn contains no photos.
Alternatively, in list comprehension syntax:
photos = [a.photos.order_by('?')[:1] for a in Album.objects.all()]
I haven't tested the code, but this is the right idea, and the select_related should help you from incurring tooooo many db queries...
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
randomPhotos = [random.choice(album.photos.objects.all()) for album in album.objects.all()]
If you make a custom method in your Album model, that looks something like this:
def random_photo(self):
import random
return random.choice(self.photos.all())
That will return a random photo from the current Album instance i.e.
albumObj.random_photo()
Note: Untested code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With