Django. Überschreiben Sie das Speichern für das Modell

Bevor ich das Modell speichere, skaliere ich ein Bild neu. Aber wie kann ich überprüfen, ob ein neues Bild hinzugefügt oder nur die Beschreibung aktualisiert wurde, sodass ich jedes Mal, wenn das Modell gespeichert wird, die Neuskalierung überspringen kann?

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) 

Ich möchte nur skalieren, wenn ein neues Bild geladen oder ein Bild aktualisiert wird, aber nicht, wenn die Beschreibung aktualisiert wird.

   

Einige Gedanken:

 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) 

Nicht sicher, ob es mit allen Pseudo-Auto-Django-Tools (Beispiel: ModelForm, contrib.admin usw.) gut spielen würde.

Überprüfen Sie das PK-Feld des Modells. Wenn es None ist, dann ist es ein neues Objekt.

 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) 

Bearbeiten: Ich habe eine Überprüfung für ‘Bild’ in form.changed_data hinzugefügt. Dies setzt voraus, dass Sie die Admin-Site verwenden, um Ihre Bilder zu aktualisieren. Sie müssen auch die Standardmethode save_model wie unten angegeben überschreiben.

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

Sie können zusätzliches Argument angeben, um zu bestätigen, dass ein neues Bild gepostet wird.
Etwas wie:

 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) 

oder übergeben Sie die Anfragevariable

 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) 

Ich denke, dass diese Ihre Rechnung nicht brechen, wenn sie einfach genannt werden.

Sie können dies in Ihre admin.py einfügen, damit dies auch mit der Admin-Site funktioniert (für die zweite der obigen Lösungen):

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

Was ich getan habe, um das Ziel zu erreichen, war, dies zu machen.

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

und unterhalb der save () Methode ist dies ..

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

Wenn ich also einige Felder bearbeite, aber das Bild nicht bearbeite, stelle ich das ..

 Model.save("skip creating photo thumbnail") 

Sie können die Option zum "skip creating photo thumbnail" durch "im just editing the description" oder einen formelleren Text ersetzen.

Hoffe dieser hilft!

Fragen Sie die database nach einem vorhandenen Datensatz mit derselben PK ab. Vergleichen Sie die Dateigrößen und Prüfsummen der neuen und vorhandenen Bilder, um festzustellen, ob sie identisch sind.

In der neuen Version ist es so:

 def validate(self, attrs): has_unknown_fields = set(self.initial_data) - set(self.fields.keys()) if has_unknown_fields: raise serializers.ValidationError("Do not send extra fields") return attrs 

Ich habe eine einfache Möglichkeit gefunden, die Daten in der database zu speichern

models.py

 class LinkModel(models.Model): link = models.CharField(max_length=500) shortLink = models.CharField(max_length=30,unique=True) 

In der database habe ich nur 2 Variablen

ansichten.py

 class HomeView(TemplateView): def post(self,request, *args, **kwargs): form = LinkForm(request.POST) if form.is_valid(): text = form.cleaned_data['link'] # text for link dbobj = LinkModel() dbobj.link = text self.no = self.gen.generateShortLink() # no for shortLink dbobj.shortLink = str(self.no) dbobj.save() # Saving from views.py 

In diesem habe ich die Instanz des Modells nur in views.py erstellt und Daten in 2 Variablen aus Ansichten nur speichern / speichern.