Get access to ForeignKey objects at parent save in

2019-06-03 19:04发布

问题:

I am trying to make a combined image of all images added to a modell in django with inline editing and a ForeignKey. Ive got these models (simplified):

class Modell(models.Model):
    title = models.CharField('beskrivelse', max_length=200)
    slug = models.SlugField()
    is_public = models.BooleanField('publisert', default=True)

    def __unicode__(self):
        return self.title

    def save(self, **kwargs):
        super(Modell, self).save(**kwargs)

        on_modell_saved(self)   

class Image(models.Model):
    modell = models.ForeignKey(Modell, related_name="images")
    image = ThumbnailImageField('bilde', upload_to=get_upload_path_image)

    class Meta:
        verbose_name = 'bilde'
        verbose_name_plural = 'bilder'

    def __unicode__(self):
        return str(self.image)

Then i add Image to the Modell with AdminInline, so when i save the Modell i save x number of images.

But when I try to do something with Modell.images.all in the on_modell_saved function i cant get hold of the objects. Ive got this function that is executed at Modell.save()

def on_modell_saved(instance):
    for img in instance.images.all():
        print img

This only prints something the second time i save the Modell and not the first time. So anybody know how to call a function after all items that you are adding with AdminInline is saved?

回答1:

Modell and Image are two seperate models connected with a ForeignKey. Even though they both seem to be saved together, they don't. They are saved one by one (first the Modell or first the Images).

Now logically Images are saved after Modell. Because they have a ForeignKey pointing to Modell and if you try to save them first, because there's no Modell yes, they would point to nothing (which is possible with null=True).

So by the time Modell.save() is called Images don't exist.

Solution depends on what you want to do? I suppose the aim here is not just printing out the Images.



回答2:

The Modell instance isn't being saved when you add a new image; only the Image instance is being saved.

Move your function call into the Image model and you'll be good.

def on_image_saved(instance):
    for img in Image.objects.filter(modell=instance.modell)
        print img

class Image(models.Model):
    modell = models.ForeignKey(Modell, related_name="images")
    image = ThumbnailImageField('bilde', upload_to=get_upload_path_image)

    class Meta:
        verbose_name = 'bilde'
        verbose_name_plural = 'bilder'

    def __unicode__(self):
        return str(self.image)

    def save(self, **kwargs):
        super(Image, self).save(**kwargs)

        on_image_saved(self)


回答3:

I dit solve it somehow, but it is farm from optimal, I did the modell_on_save function on Image save, this works, but the bad thing that if there are 5 images related and saved to the modell, there will be 5 calls to the function, and that is bad. I would like it to only happen after the last one...