我有一個Django查詢和一些我試圖優化的Python代碼,因爲1)它很醜並且不像我可以用來編寫它的一些SQL那樣高性能,2)因爲數據的分層重組看起來很亂對我來說。如何改進這個多對多的Django ORM查詢和模型集?
因此, 1.是否有可能改進這是一個單一的查詢? 2.如何提高我的Python代碼以使其變得更加Pythonic?
背景
這是一個圖片庫系統。特定視圖試圖顯示畫廊中所有照片的縮略圖。每張照片靜態大小几次,以避免動態調整大小,我還想檢索每個大小的URL和「大小類型」(例如縮略圖,中等,大),以便我可以在不觸碰數據庫的情況下對備用大小進行Lightbox 。
實體
我有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)
所以,粗略的想法是,我想獲得的所有照片通過文件庫一庫,併爲每個照片,我想獲取所有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部分
我看看這段代碼,我不與它的樣子太激動。我當然希望有一種更好的方法可以將分層查詢集結果按列名分組到字典中。在那兒?
我喜歡這個主意......非常有趣的尼古拉。 – Jordan
它幫助我極大地減少了重頁上的查詢次數。 –