У меня есть запрос Django и некоторый код Python, который я пытаюсь оптимизировать, потому что 1) он уродлив и не так эффективен, как какой-то SQL, который я мог бы использовать для его записи, и 2) потому что иерархическая перегруппировка данных выглядитгрязный для меня.
Итак, 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)
Итак, грубая идея в том, что я хотел бы получитьвсе фотографии в галерее через GalleryPhoto, и для каждой фотографии я хочу получить все размеры фотографий, и я хотел бы иметь возможность циклически просматривать и получать доступ ко всем этим данным через словарь.
Черновой набросок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
Iпосмотрите на этот код, и я не слишком взволнован тем, как он выглядит.Я уверен, что есть лучший способ сгруппировать результаты иерархического набора запросов по имени столбца в словарь.Есть ли?