pol
Antes de guardar el modelo, cambio el tamaño de una imagen. Pero, ¿cómo puedo verificar si se agregó una nueva imagen o solo se actualizó la descripción, para poder omitir el cambio de escala cada vez que se guarda el modelo?
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)
Quiero cambiar la escala solo si se carga una nueva imagen o se actualiza una imagen, pero no cuando se actualiza la descripción.
petraszd
Algunos pensamientos:
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)
No estoy seguro de si funcionaría bien con todas las herramientas pseudo-automáticas de django (Ejemplo: ModelForm, contrib.admin, etc.).
-
Se ve bien. Pero no puedo cambiar el nombre de la imagen a _image. ¿Es eso importante?
– Pol
24 de noviembre de 2010 a las 18:30
-
Ok, lo resolví con db_column=’image’. ¡Pero el acero no funciona!
– Pol
24 de noviembre de 2010 a las 18:34
-
Es un método muy interesante… por no entenderlo del todo. ¿Puedes explicarlo más explicativamente? ¿O sembrar algún artículo?
– Pol
24 de noviembre de 2010 a las 19:57
-
A mí tampoco me ha funcionado. set_image nunca llamó. Parece que esto es algo que Django no admite oficialmente.
– Iván Borshchov
8 abr 2017 a las 9:50
Tumbas de DM
Compruebe el campo pk del modelo. Si es Ninguno, entonces es un objeto nuevo.
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)
Editar: he agregado un cheque para ‘imagen’ en form.changed_data. Esto supone que está utilizando el sitio de administración para actualizar sus imágenes. También tendrá que anular el método save_model predeterminado como se indica a continuación.
class ModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.save(form=form)
-
Creo que tiene razón… suponiendo que esté usando el sitio de administración, puede anular save_model en su AdminModel para pasar el formulario para guardarlo y verificar si la ‘imagen’ está en form.changed_data. Actualizaré en cuanto tenga tiempo.
– DM Tumbas
24 de noviembre de 2010 a las 20:10
-
Esto solo funciona si el objeto es nuevo como dices. Si carga una imagen nueva, no se activará el cambio de escala.
– Jonathan
8 de julio de 2014 a las 14:37
-
“self.pk is None” no funciona si se especifica el id, por lo que: Model.objects.get_or_create(id=234,…) no funcionará en esta solución
– nueces
10 de diciembre de 2014 a las 10:27
crodjer
Puede proporcionar un argumento adicional para confirmar que se publica una nueva imagen.
Algo como:
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)
o pasar la variable de solicitud
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)
Creo que estos no romperán su ahorro cuando se llamen simplemente.
Puede poner esto en su admin.py para que funcione también con el sitio de administración (para la segunda de las soluciones anteriores):
class ModelAdmin(admin.ModelAdmin):
....
def save_model(self, request, obj, form, change):
instance = form.save(commit=False)
instance.save(request=request)
return instance
-
me dice que: el objeto ‘WSGIRequest’ no tiene atributo ‘ARCHIVO’
– Pol
24 de noviembre de 2010 a las 18:01
-
sry sus ARCHIVOS en lugar de ARCHIVO, actualizado a solicitud.ARCHIVOS.get(‘imagen’, Falso) en lugar de solicitud.ARCHIVOS[‘image’]esto evitará la excepción
– crodjer
24 de noviembre de 2010 a las 18:03
Consultar la base de datos para un registro existente con el mismo PK. Compare los tamaños de archivo y las sumas de verificación de las imágenes nuevas y existentes para ver si son iguales.
Lo que hice para lograr el objetivo fue hacer esto..
# I added an extra_command argument that defaults to blank
def save(self, extra_command="", *args, **kwargs):
y debajo del método save() está esto …
# override the save method to create an image thumbnail
if self.image and extra_command != "skip creating photo thumbnail":
# your logic here
entonces, cuando edito algunos campos pero no edito la imagen, pongo esto …
Model.save("skip creating photo thumbnail")
puedes reemplazar el "skip creating photo thumbnail"
con "im just editing the description"
o un texto más formal.
¡Espero que esto ayude!
Fruchtzwerg
En la nueva versión es así:
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
Devendra Bhat
He encontrado otra forma sencilla de almacenar los datos en la base de datos.
modelos.py
class LinkModel(models.Model):
link = models.CharField(max_length=500)
shortLink = models.CharField(max_length=30,unique=True)
En la base de datos solo tengo 2 variables.
vistas.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
En esto, he creado la instancia del modelo solo en views.py y he puesto/guardado datos en 2 variables solo desde las vistas.
¿Está cambiando el tamaño a un tamaño fijo de 100×100?
– bdd
24 de noviembre de 2010 a las 17:23
Puedes encontrar django-imagekit útil
– vikingosegundo
24 de noviembre de 2010 a las 18:12
Véanse también las notas en documentación.
– djvg
14/09/2022 a las 16:51