我有多个与单个模型相关的模型。在保存这些模型时,我覆盖了 save 以检索主模型的 id,以便将文件放在 OS 上由主模型的 pk 键入的目录中。
例如,以具有许多房间的建筑物为例。房间的任何图像都将保存在由建筑物 ID 键入的目录中(房间没有子目录)。
只要保存房间时建筑物存在,我的覆盖保存方法就可以正常工作。但是,如果尚未保存建筑物,并且我正在通过 django 管理员向建筑物添加房间,则图像仍保留在上传目录中,因为该建筑物的 pk 尚不存在。
我最初尝试覆盖建筑物的保存并将任何房间图像移动到新创建的建筑物目录(再次关闭建筑物的 pk)。尽管 super(Building, self).save(*args, **kwargs) 首先没有设置 Building 的 id。
然后我决定 post_save 信号可能更干净,并且这样做了。不幸的是,该 id 似乎也不存在于帖子保存中。我可以尝试打印 ID 并在触发后保存时看不到任何值,直到我第二次保存模型。
有人可以向我指出一个方向,可以解释为什么 id 没有像其他 SO 答案中所接受的预期输出那样设置吗?
谢谢。
编辑:
这是评论中要求的一些代码。因为我简化了最初的问题,所以我在这里包含更多内容。这里有 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