Przed zapisaniem modelu zmieniam rozmiar obrazu. Ale jak mogę sprawdzić, czy dodano nowe zdjęcie, czy tylko zaktualizowany opis, aby móc pominąć przeskalowanie za każdym razem, gdy model jest zapisywany?
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)
Chcę przeskalować tylko po załadowaniu nowego obrazu lub aktualizacji obrazu, ale nie po zaktualizowaniu opisu.
Odpowiedzi:
Kilka myśli:
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)
Nie jestem pewien, czy dobrze by działał ze wszystkimi narzędziami pseudo-auto django (przykład: ModelForm, contrib.admin itp.).
źródło
Sprawdź pole pk modelu. Jeśli jest brak, jest to nowy obiekt.
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)
Edycja: dodałem czek dla „obrazu” w form.changed_data. Zakłada się, że używasz witryny administratora do aktualizowania obrazów. Będziesz także musiał zastąpić domyślną metodę save_model, jak wskazano poniżej.
class ModelAdmin(admin.ModelAdmin): def save_model(self, request, obj, form, change): obj.save(form=form)
źródło
Możesz podać dodatkowy argument za potwierdzeniem opublikowania nowego zdjęcia.
Coś jak:
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)
lub przekazać zmienną żądania
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)
Myślę, że te nie zepsują twojego zapisu, gdy zostaną po prostu wywołane.
Możesz umieścić to w swoim admin.py, aby działało również z witryną administracyjną (dla drugiego z powyższych rozwiązań):
class ModelAdmin(admin.ModelAdmin): .... def save_model(self, request, obj, form, change): instance = form.save(commit=False) instance.save(request=request) return instance
źródło
Aby osiągnąć cel, zrobiłem to ...
# I added an extra_command argument that defaults to blank def save(self, extra_command="", *args, **kwargs):
a poniżej metody save () jest to ...
# override the save method to create an image thumbnail if self.image and extra_command != "skip creating photo thumbnail": # your logic here
więc kiedy edytuję niektóre pola, ale nie edytuję obrazu, umieszczam to ...
Model.save("skip creating photo thumbnail")
można wymienić
"skip creating photo thumbnail"
z"im just editing the description"
lub bardziej formalne tekstu.Mam nadzieję, że ten pomoże!
źródło
Zapytaj bazę danych o istniejący rekord o tej samej PK. Porównaj rozmiary plików i sumy kontrolne nowych i istniejących obrazów, aby sprawdzić, czy są takie same.
źródło
W nowej wersji wygląda to tak:
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
źródło
Znalazłem inny prosty sposób na przechowywanie danych w bazie danych
models.py
class LinkModel(models.Model): link = models.CharField(max_length=500) shortLink = models.CharField(max_length=30,unique=True)
W bazie danych mam tylko 2 zmienne
views.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
W tym utworzyłem instancję modelu tylko w views.py i umieszczając / zapisując dane w 2 zmiennych tylko z widoków.
źródło