2009-07-16 35 views
7

Đang cố gắng lấy một ảnh ngẫu nhiên từ mỗi album từ dữ liệu được tạo bởi syncr. Mô hình (viết tắt) trông giống như sau:Django - Chọn một ảnh ngẫu nhiên từ mỗi Album


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

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

Tôi đã thử nhiều cách tiếp cận khác nhau không thành công. Đây có phải là một cách dễ dàng khác không?

Take 2: Mã cuối cùng:

phòng trưng bày def (yêu cầu, 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

học được rất nhiều từ tất cả các câu trả lời và cuối cùng sử dụng một sự kết hợp. Cảm ơn rất nhiều tất cả: phòng trưng bày def (yêu cầu, TEMPLATE_NAME = 'galleries.html'): album = Album.objects.select_related() tất cả() album_list = [] cho album trong album:. album_list. chắp thêm ({'title': album.title, 'id': album.id, 'photo': album.random_photo()}) trả lại render_to_response (template_name, { "album_list": album_list, }) – PhoebeB

Trả lời

8

tôi đã không kiểm tra mã này, nhưng đây là ý tưởng đúng, và select_related sẽ giúp bạn phát sinh nhiều lượt truy cập 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

Cần phải làm điều gì đó hơi khác nhau ở giữa vì giả định ảnh tất cả đều có các khóa chính trong phạm vi từ 0 đến tổng. Tôi có thể lấy một phần tử ngẫu nhiên từ danh sách tất cả album.photos không? – 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 , danh sách hiểu, tốt đẹp! –

+0

cho anbom trong Album.objects.all() –

+0

Đã thử: >>> nhập ngẫu nhiên >>> randomPhotos = [random.choice (album.photos.objects.tất cả()) cho album trong Album.objects.all()] và nhận điều này: Traceback (cuộc gọi gần đây nhất): Tệp "", dòng 1, in? AttributeError: đối tượng 'ManyRelatedManager' không có thuộc tính 'đối tượng' >>> – PhoebeB

3

Nếu bạn thực hiện một phương pháp tùy chỉnh trong mô hình Album của bạn, mà trông giống như sau:

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

Đó sẽ trả về một ảnh ngẫu nhiên từ dụ Album hiện tại tức là

albumObj.random_photo() 

Lưu ý: Mã chưa được kiểm tra

24

Bạn có thể nhận được một đơn đối tượng ngẫu nhiên từ bất kỳ Queryset nào sử dụng phương thức order_by với dấu chấm hỏi làm đối số. Điều này có thể tốt hơn là gọi Photo.objects.all() vì nó sẽ chỉ trả lại một đối tượng ảnh cho mỗi truy vấn từ cơ sở dữ liệu, chứ không phải toàn bộ và sau đó sử dụng python để lọc danh sách.

Ví dụ, truy vấn này sẽ trả về một ảnh ngẫu nhiên duy nhất:

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

Sau đây là không tối ưu, bởi vì nó cần 1 truy vấn cho mỗi album, nhưng nó sẽ làm việc:

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

Chỉnh sửa: Đã thay đổi chỉ số [0] thành [:1] vì trước đây sẽ tăng chỉ số IndexError nếu albumn không chứa ảnh.

Ngoài ra, trong danh sách hiểu cú pháp:

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

+1: có vẻ như đây là cách hay để làm điều đó và nếu Tôi có thể cung cấp cho bạn một +1 khác để dạy tôi điều gì đó về order_by mà tôi không biết! cảm ơn! – SingleNegationElimination

+0

+1 cho kiến ​​thức order_by. – Harold

+0

vui lòng xem http://buffis.com/2008/01/20/how-to-get-random-rows-from-mysql-using-django/comment-page-1/ – chefsmart

Các vấn đề liên quan