2009-07-16 4 views
7

Я пытаюсь получить случайную фотографию из каждого альбома из данных, созданных syncr. Модель (сокращенно) выглядит так:Django - выберите случайное фото из каждого альбома


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

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

Я пробовал много разных подходов без успеха. Это еще один легкий?

Take 2: Конечный код:

DEF галереи (запрос, 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

Узнал много от всех этих ответов и в конце концов использовал комбинацию. Большое спасибо всем: Защита галерея (запрос, TEMPLATE_NAME = 'galleries.html'): альбомов = Album.objects.select_related() все() album_list = [] для альбома в альбоме:. album_list. присоединять ({ 'название': album.title 'ID': album.id, 'фото': album.random_photo()}) возвращение render_to_response (template_name, { "album_list": album_list, }) – PhoebeB

ответ

8

Я не проверял код, но это правильная идея, и select_related должны помочь вам понести tooooo много запросов БД ...

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

Нужно сделать что-то немного другое посередине, так как предполагается, что фотографии имеют первичные ключи в диапазоне от 0 до общего. Могу ли я получить случайный элемент из списка всех альбомов. – 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

ооо , перечислить понимание, приятно! –

+0

для альбома в альбоме.objects.all() –

+0

Пробовал это: >>> import random >>> randomPhotos = [random.choice (album.photos.objects.все()) для альбома в Album.objects.all()] и получил эту: TraceBack (самый последний вызов последнего): Файл "", строка 1, в? AttributeError: объект 'ManyRelatedManager' не имеет атрибутов 'objects' >>> – PhoebeB

3

Если вы сделаете специальный метод в модели альбома, который выглядит примерно так:

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

Это возвращает случайное фото из текущего экземпляра альбома т.е.

albumObj.random_photo() 

Примечания: неопробованный код

24

Вы можете получить один случайный объект из любого Queryset с использованием метода order_by с вопросительным знаком в качестве аргумента. Это может быть лучше, чем вызов Photo.objects.all(), поскольку он будет возвращать только один фотообъект за запрос из базы данных, а не весь набор, а затем использовать python для фильтрации списка.

Например, этот запрос будет возвращать одно случайное фото:

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

Ниже не является оптимальным, так как он нуждается в 1 запрос для каждого альбома, но это будет работать:

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

Редактировать: Изменен индекс [0] на [:1], поскольку первый будет поднять IndexError, если в альбоме нет фото.

Кроме того, в списке понимания синтаксиса:

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

+1: похоже, что это хороший способ сделать это, и если Я мог бы дать тебе еще +1 за то, что научил меня что-то о order_by, которого я не знал! благодаря! – SingleNegationElimination

+0

+1 для знака order_by. – Harold

+0

см. Http://buffis.com/2008/01/20/how-to-get-random-rows-from-mysql-using-django/comment-page-1/ – chefsmart

Смежные вопросы