172 votes

Django. Remplacer l'enregistrement pour le modèle

Avant d'enregistrer le modèle, je redimensionne une image. Mais comment puis-je vérifier si une nouvelle image a été ajoutée ou simplement une description mise à jour, afin de pouvoir sauter la mise à l'échelle à chaque fois que le modèle est enregistré ?

class Model(model.Model):
    image=models.ImageField(upload_to='folder')
    thumb=models.ImageField(upload_to='folder')
    description=models.CharField()


    def save(self, *args, **kwargs):
        if self.image:
            small=rescale_image(self.image,width=100,height=100)
            self.image_small=SimpleUploadedFile(name,small_pic)
        super(Model, self).save(*args, **kwargs)

Je veux redimensionner uniquement si une nouvelle image est chargée ou mise à jour, mais pas lorsque la description est mise à jour.

162voto

petraszd Points 1637

Quelques réflexions :

class Model(model.Model):
    _image=models.ImageField(upload_to='folder')
    thumb=models.ImageField(upload_to='folder')
    description=models.CharField()

    def set_image(self, val):
        self._image = val
        self._image_changed = True

        # Or put whole logic in here
        small = rescale_image(self.image,width=100,height=100)
        self.image_small=SimpleUploadedFile(name,small_pic)

    def get_image(self):
        return self._image

    image = property(get_image, set_image)

    # this is not needed if small_image is created at set_image
    def save(self, *args, **kwargs):
        if getattr(self, '_image_changed', True):
            small=rescale_image(self.image,width=100,height=100)
            self.image_small=SimpleUploadedFile(name,small_pic)
        super(Model, self).save(*args, **kwargs)

Je ne suis pas sûr qu'il jouerait bien avec tous les outils django pseudo-auto (Exemple : ModelForm ,breg.admin etc).

21voto

graveyboat Points 186

Vérifiez le champ pk du modèle. Si c'est None, alors c'est un nouvel objet.

class Model(model.Model):
    image=models.ImageField(upload_to='folder')
    thumb=models.ImageField(upload_to='folder')
    description=models.CharField()


    def save(self, *args, **kwargs):
        if 'form' in kwargs:
            form=kwargs['form']
        else:
            form=None

        if self.pk is None and form is not None and 'image' in form.changed_data:
            small=rescale_image(self.image,width=100,height=100)
            self.image_small=SimpleUploadedFile(name,small_pic)
        super(Model, self).save(*args, **kwargs)

Modifier : J'ai ajouté un chèque pour 'image' dans form.changé_data. Cela suppose que vous utilisez le site d'administration pour mettre à jour vos images. Vous devrez également remplacer la méthode par défaut save_model comme indiqué ci-dessous.

class ModelAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.save(form=form)

9voto

crodjer Points 4099

Vous pouvez fournir un argument supplémentaire pour confirmer qu'une nouvelle image est publiée.
Quelque chose comme :

def save(self, new_image=False, *args, **kwargs):
    if new_image:
        small=rescale_image(self.image,width=100,height=100)
        self.image_small=SimpleUploadedFile(name,small_pic)
    super(Model, self).save(*args, **kwargs)

ou variable de demande de passage

def save(self, request=False, *args, **kwargs):
    if request and request.FILES.get('image',False):
        small=rescale_image(self.image,width=100,height=100)
        self.image_small=SimpleUploadedFile(name,small_pic)
    super(Model, self).save(*args, **kwargs)

Je pense que ça ne cassera pas votre sauvegarde quand on vous appelle tout simplement.

Vous pouvez le mettre dans votre admin.py afin que ce travail avec le site d'administration aussi (pour la deuxième des solutions ci-dessus) :

class ModelAdmin(admin.ModelAdmin):

    ....
    def save_model(self, request, obj, form, change): 
        instance = form.save(commit=False)
        instance.save(request=request)
        return instance

4voto

bonbon.langes Points 189

Ce que j'ai fait pour atteindre l'objectif était de le faire..

# I added an extra_command argument that defaults to blank
def save(self, extra_command="", *args, **kwargs):

et en dessous de la méthode save() est ceci..

# override the save method to create an image thumbnail
if self.image and extra_command != "skip creating photo thumbnail":
    # your logic here

Donc quand je modifie certains champs mais pas l'image, je mets ceci..

Model.save("skip creating photo thumbnail")

vous pouvez remplacer "skip creating photo thumbnail" par "im just editing the description" ou un texte plus formel.

J'espère que ça aidera !

3voto

Cherchez dans la base de données un enregistrement existant avec la même PK. Comparez les tailles de fichiers et les sommes de contrôle des images nouvelles et existantes pour voir si elles sont les mêmes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X