Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 保存后,模型id不存在_Django_Django Models_Django Admin_Django Signals - Fatal编程技术网

Django 保存后,模型id不存在

Django 保存后,模型id不存在,django,django-models,django-admin,django-signals,Django,Django Models,Django Admin,Django Signals,我有多个模型与单个模型相关。在保存这些模型时,我已经覆盖了save来检索主模型的id,以便将操作系统上的文件放在主模型pk键控的目录中 例如,以一座有许多房间的建筑为例。房间的任何图像都将保存在由建筑物id键入的目录中(房间没有子目录) 只要保存房间时建筑存在,我的重写保存方法就可以正常工作。但是,如果该建筑尚未保存,并且我正在通过django管理员向该建筑添加一个房间,则该图像将保留在上载目录中,因为该建筑尚不存在pk 我最初尝试覆盖建筑物上的保存,并将所有房间图像移动到新创建的建筑物目录(再

我有多个模型与单个模型相关。在保存这些模型时,我已经覆盖了save来检索主模型的id,以便将操作系统上的文件放在主模型pk键控的目录中

例如,以一座有许多房间的建筑为例。房间的任何图像都将保存在由建筑物id键入的目录中(房间没有子目录)

只要保存房间时建筑存在,我的重写保存方法就可以正常工作。但是,如果该建筑尚未保存,并且我正在通过django管理员向该建筑添加一个房间,则该图像将保留在上载目录中,因为该建筑尚不存在pk

我最初尝试覆盖建筑物上的保存,并将所有房间图像移动到新创建的建筑物目录(再次键入建筑物的pk)。尽管super(Building,self).save(*args,**kwargs)首先未设置建筑的id

然后我决定后保存信号可能更干净,无论如何,这样做。不幸的是,post save中似乎也不存在该id。在第二次保存模型之前,我可以尝试打印ID,但在触发后期保存时看不到任何值

有人能给我指出一个方向来解释为什么id并没有被设置为中所接受的预期输出吗

谢谢

编辑:

下面是一些注释中要求的代码。由于我简化了最初的问题,这里我将包含更多内容。这里有3层,一个带房间的建筑物列表。我试图通过
printKwargs['instance']
行简单地打印这个列表。在底部,我包含了两次背靠背保存后的输出。请注意,在第一次保存后,完全没有实例存在。实际上,它们是背靠背的,彼此之间没有任何动作。通过桌子来引用像建筑房间这样的东西。除了数据字段之外,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

好的,问题看起来是因为你使用了很多关系。看看这些帖子:

我会考虑重构你的代码来改变建筑物和房间之间的关系。现在你说的是“有很多房间,一座建筑物可以与其中的一些房间相关联”。此外,两栋建筑可以与同一个房间相关联。这真的没有道理。实际上,一个房间应该只与一个建筑物相关联,即

class Building(models.Model):
    name = models.CharField(...)
    ...

class Room(models.Model):
    building = models.ForeignKey(Building, unique=True)
    ....

这意味着任何房间只能链接到一个特定的建筑

首先,帕斯蒂格斯是对的,他的答案更好。但是,如果出于某种原因(比如我现在)由于任何原因无法更改代码,并且发现自己在post_save model实例中不存在问题,就像我们在过去几天中发现的那样,下面的想法可能会有所帮助

在我们的例子中,通过表中的manytomany就足以进行后期保存。通过将post save信号附加到through表本身,我们基本上能够捕获我们需要进行post_保存的所有情况,并且作为through表中存在的多个关系的两个连接表的ID,这就足以完成任务。因此,如果您发现自己出于类似的原因出现在这里,是否可以将post_save附加到直通表


同样,pastylegs是对的,但如果出于任何原因您不能这样做,我希望这会有所帮助。

您确定保存后的信号是附加在建筑物的保存上,而不是房间的保存上吗?你能把你的信号贴在哪里吗?如果在保存建筑后信号触发,那么您没有理由看不到id(除非您使用commit=False保存,在这种情况下,我不确定信号是否触发?)我非常确定post save已附加到正确的模型,因为我已设置了发送器,并且在第一次后立即保存第二次后也会获得预期的输出。信号/注册装饰器和相关模型代码已包含在编辑中。No commit=False。所包含的输出引用了信号。感谢您的支持我们的帮助,我的想法是困惑的…希望我正在做一些明显的事情。谢谢。完全是因为你在外键上,而不是很多想法。我认为促使我们使用很多的是我们使用的贯穿/贯穿模型。现在我们有贯穿桌子的内联线(即构建房间)。我们这样做是为了解决缺少嵌套内联的问题。单击“编辑”“在建筑上,内联显示该参照建筑的建筑管理显示。现在,在我们能够找到更好的解决方案之前,我们可以尝试在through表上进行post_save。很快就要尝试了。谢谢你的帮助,我感觉到了你的困境!你应该小心,不要(像我一样)落入基于django admin功能设计数据库和业务逻辑的陷阱-这些限制通常是由于前端代码造成的,弯曲后端设计以简化生活有时会导致问题。是的,正是我一直在想的。但这里的情况有点落后(设计糟糕的模型-->基于那些-->现在无法轻松更改的模型构建的管理员)。起初,我们认为出于某种原因需要m2m(不知道为什么),然后我们构建了管理员。因此,我们的管理员现在过于依赖我们设计错误的数据库,无法修复它。再次感谢您的帮助和建议。