【问题标题】:Django - Select a random photo from each AlbumDjango - 从每个相册中随机选择一张照片
【发布时间】:2010-11-11 11:08:46
【问题描述】:

我正在尝试从 syncr 创建的数据中从每个相册中获取随机照片。模型(缩写)如下所示:


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,
})

【问题讨论】:

  • 从所有这些答案中学到了很多,并最终使用了一个组合。非常感谢所有: def gallery(request, template_name='galleries.html'): albums = Album.objects.select_related().all() album_list = [] 专辑中的专辑:album_list.append({'title': album.title, 'id':album.id, 'photo':album.random_photo()}) return render_to_response(template_name, { "album_list": album_list, })

标签: django django-queryset


【解决方案1】:

您可以使用带有问号作为参数的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()]

【讨论】:

  • +1:看起来这是一个很好的方法,如果可以的话,我会再给你一个 +1 来教我一些关于 order_by 我不知道的事情!谢谢!
  • 阅读您的博客文章 chefsmart。如果其中一条记录被删除,或者由于某些其他原因,ID 集不是从 1 开始的连续的连续集,在您的示例中会发生什么?
  • 如果您使用数据库缓存(如 Johnny 缓存),order_by('?') 对于很少编辑的表几乎毫无用处。
【解决方案2】:

我还没有测试过代码,但这是正确的想法,并且 select_related 应该可以帮助您避免引发过多的数据库查询...

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 到总计的范围内。我可以从所有专辑照片列表中获取随机元素吗?
【解决方案3】:
randomPhotos = [random.choice(album.photos.objects.all()) for album in album.objects.all()]

【讨论】:

  • 哦,列表理解,很好!
  • 对于 Album.objects.all() 中的专辑
  • 试过这个:>>> import random >>> randomPhotos = [random.choice(album.photos.objects.all()) for album in Album.objects.all()] 并得到了这个:回溯(最近一次调用最后一次):文件“”,第 1 行,在? AttributeError: 'ManyRelatedManager' 对象没有属性 'objects' >>>
  • 从album.photos.objects.all()中移除单词objects
【解决方案4】:

如果您在 Album 模型中创建自定义方法,则如下所示:

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

这将从当前相册实例返回一张随机照片,即

albumObj.random_photo()

注意:未经测试的代码

【讨论】:

    猜你喜欢
    • 2011-05-10
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多