У меня есть несколько моделей, которые относятся к одной модели. При сохранении этих моделей я перезаписал сохранение, чтобы получить идентификатор основной модели, чтобы поместить файлы в ОС в каталог с ключом pk основной модели.
Например, возьмем здание с множеством комнат. Любые изображения комнат будут сохранены в каталоге с ключом идентификатора здания (без подкаталога для комнат).
Мои переопределенные методы сохранения работают нормально, пока здание существует, когда комната сохраняется. Однако, если здание еще не сохранено, и я добавляю комнату в здание через администратора django, изображение остается в каталоге загрузки, поскольку pk для здания еще не существует.
Первоначально я попытался переопределить сохранение при построении и переместить любые изображения комнат во вновь созданный каталог зданий (опять же отключил pk здания). Несмотря на супер (Building, self) .save (* args, ** kwargs), сначала идентификатор здания не был установлен.
Затем я решил, что сигнал post_save, вероятно, все-таки чище и сделал так. К сожалению, идентификатор не существует в записи, кроме как. Я могу попытаться напечатать идентификатор и не вижу значения, когда после сохранения будет запущено сохранение, пока я не сохраню модель во второй раз.
Может ли кто-нибудь указать мне направление, которое могло бы объяснить, почему идентификатор не устанавливается так, как ожидалось бы, как принято в этом другом ответе SO ?
Спасибо.
Edit:
Вот код, запрошенный в комментарии. Я включил немного больше здесь, поскольку я упростил первоначальный вопрос. Здесь есть 3 уровня, распечатка со зданиями с комнатами. Список - это то, что я пытаюсь просто напечатать через строку print kwargs['instance']
. Внизу я включил вывод после двух последовательных сохранений. Обратите внимание на полное отсутствие существующего экземпляра после первого сохранения. Они были буквально спина к спине без каких-либо действий между Ссылки на такие вещи, как Building_Room, проходят через таблицы. RoomImage, BuildingImage и ListingImage все похожи, кроме полей данных, и поэтому я включил только одно.
class Listing(models.Model):
...
buildings = models.ManyToManyField('Building', null=True, blank=True, through = 'Building_Listing')
addresses = models.ManyToManyField(Address, null=True, blank=True)
def __unicode__(self):
return ' & '.join([a.__unicode__() for a in self.addresses.all()])
class Building(models.Model):
...
rooms = models.ManyToManyField('Room', null=True, through="Building_Room")
def __unicode__(self):
return self.description
class Room(models.Model):
...
def __unicode__(self):
return str(self.room_type)
class RoomImage(models.Model):
room = models.ForeignKey(Room)
room_photo = FileBrowseField("Image", max_length=200, blank=True, null=True)
def save(self, *args, **kwargs):
try:
listing = Building_Listing.objects.get(building=Building_Room.objects.get(room=self.room).building).listing
self.room_photo = moveFileBeforeSave(listing, self.room_photo)
except Building_Listing.DoesNotExist:
pass
except Building_Room.DoesNotExist:
pass
super(RoomImage, self).save(*args, **kwargs)
@receiver(post_save, sender=Listing, weak=False)
def save_images_on_listing_create(sender, **kwargs):
#if kwargs['created']:
listing = kwargs['instance']
print kwargs['instance']
listing_image_list = ListingImage.objects.filter(listing = listing)
listing_buildings = Building_Listing.objects.filter(listing = listing).values_list('building', flat=True)
building_image_list = BuildingImage.objects.filter(building__in = listing_buildings)
building_rooms = Building_Room.objects.filter(building__in = listing_buildings).values_list('room', flat=True)
room_image_list = RoomImage.objects.filter(room__in = building_rooms)
for image in listing_image_list:
image.save()
for image in building_image_list:
image.save()
for image in room_image_list:
image.save()
@receiver(post_save, sender=Building, weak=False)
def save_images_in_building_create(sender, **kwargs):
#if kwargs['created']:
print str(kwargs['instance'])+" : building save trigger"
building = kwargs['instance']
building_image_list = BuildingImage.objects.filter(building = building)
building_rooms = Building_Room.objects.filter(building = building).values_list('room', flat=True)
room_image_list = RoomImage.objects.filter(room__in = building_rooms)
for image in building_image_list:
image.save()
for image in room_image_list:
image.save()
Некоторый вывод:
[30/Oct/2011 19:52:05] "POST /admin/mls/building/add/?_popup=1 HTTP/1.1" 200 97
# This is the print of the instance kwarg after the first save (ie nothing)
[30/Oct/2011 19:52:10] "POST /admin/mls/listing/add/ HTTP/1.1" 302 0
[30/Oct/2011 19:52:10] "GET /admin/mls/listing/8/ HTTP/1.1" 200 72495
[30/Oct/2011 19:52:10] "GET /admin/jsi18n/ HTTP/1.1" 200 2158
1 Ben Blvd sometown, MN #this is the print of the instance kwarg after the second save
[30/Oct/2011 19:52:12] "POST /admin/mls/listing/8/ HTTP/1.1" 302 0
[30/Oct/2011 19:52:13] "GET /admin/mls/listing/8/ HTTP/1.1" 200 72497
[30/Oct/2011 19:52:13] "GET /admin/jsi18n/ HTTP/1.1" 200 2158