【发布时间】:2012-01-12 05:46:25
【问题描述】:
我有一个 Django 查询和一些我正在尝试优化的 Python 代码,因为 1)它很丑,而且它的性能不如我可以用来编写它的某些 SQL,以及 2)因为数据的分层重组看起来对我来说很乱。
所以, 1.是否可以将其改进为单个查询? 2. 如何改进我的 Python 代码使其更加 Pythonic?
背景
这是一个照片库系统。特定视图试图显示画廊中所有照片的缩略图。每张照片都经过多次静态调整以避免动态调整大小,我还想检索每个大小的 URL 和“大小类型”(例如缩略图、中、大),这样我就可以在不再次访问数据库的情况下将备用大小装箱.
实体
我有 5 个相关的模型:
class Gallery(models.Model):
Photos = models.ManyToManyField('Photo', through = 'GalleryPhoto', blank = True, null = True)
class GalleryPhoto(models.Model):
Gallery = models.ForeignKey('Gallery')
Photo = models.ForeignKey('Photo')
Order = models.PositiveIntegerField(default = 1)
class Photo(models.Model):
GUID = models.CharField(max_length = 32)
class PhotoSize(models.Model):
Photo = models.ForeignKey('Photo')
PhotoSizing = models.ForeignKey('PhotoSizing')
PhotoURL = models.CharField(max_length = 1000)
class PhotoSizing(models.Model):
SizeName = models.CharField(max_length = 20)
Width = models.IntegerField(default = 0, null = True, blank = True)
Height = models.IntegerField(default = 0, null = True, blank = True)
Type = models.CharField(max_length = 10, null = True, blank = True)
所以,粗略的想法是,我想通过 GalleryPhoto 获取 Gallery 中的所有照片,并且对于每张照片,我想获取所有 PhotoSizes,并且我希望能够循环访问并访问所有这些通过字典获取数据。
SQL 的粗略草图可能如下所示:
Select PhotoSize.PhotoURL
From PhotoSize
Inner Join Photo On Photo.id = PhotoSize.Photo_id
Inner Join GalleryPhoto On GalleryPhoto.Photo_id = Photo.id
Inner Join Gallery On Gallery.id = GalleryPhoto.Gallery_id
Where Gallery.id = 5
Order By GalleryPhoto.Order Asc
我想把它变成一个具有如下架构的列表:
(
photo: {
'guid': 'abcdefg',
'sizes': {
'Thumbnail': 'http://mysite/image1_thumb.jpg',
'Large': 'http://mysite/image1_full.jpg',
more sizes...
}
},
more photos...
)
我目前有以下 Python 代码(它并不完全模仿上面的架构,但它可以作为示例)。
gallery_photos = [(photo.Photo_id, photo.Order) for photo in GalleryPhoto.objects.filter(Gallery = gallery)]
photo_list = list(PhotoSize.objects.select_related('Photo', 'PhotoSizing').filter(Photo__id__in=[gallery_photo[0] for gallery_photo in gallery_photos]))
photos = {}
for photo in photo_list:
order = 1
for gallery_photo in gallery_photos:
if gallery_photo[0] == photo.Photo.id:
order = gallery_photo[1] //this gets the order column value
guid = photo.Photo.GUID
if not guid in photos:
photos[guid] = { 'Photo': photo.Photo, 'Thumbnail': None, 'Sizes': [], 'Order': order }
photos[guid]['Sizes'].append(photo)
sorted_photos = sorted(photos.values(), key=operator.itemgetter('Order'))
实际问题,第 1 部分
所以,我的问题首先是我是否可以更好地进行多对多查询,这样我就不必对 gallery_photos 和 photo_list 进行双重查询。
实际问题,第 2 部分
我查看了这段代码,但对它的外观并不太满意。我当然希望有一种更好的方法可以通过列名将分层查询集结果分组到字典中。有吗?
【问题讨论】:
标签: python sql django postgresql django-models