2010-11-24 24 views
83

Antes de guardar el modelo, me vuelvo a clasificar según el tamaño una imagen. Pero, ¿cómo puedo verificar si se agregó una nueva imagen o solo se actualizó la descripción, por lo que puedo omitir el cambio de escala cada vez que se guarda el modelo?Django. Reemplazar guardar para 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 volver a escalar solo si se cargó una nueva imagen o se actualizó la imagen, pero no cuando se actualizó la descripción.

+0

¿Está el cambio de tamaño a un tamaño fijo de 100x100? – bdd

+1

U puede encontrar [django-imagekit] (http://bitbucket.org/jdriscoll/django-imagekit/wiki/Home) – vikingosegundo

Respuesta

91

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 si jugaría bien con todas las herramientas django pseudo-auto (Ejemplo: ModelForm, contrib.admin, etc.).

+1

Se ve bien. Pero no puedo cambiar el nombre de la imagen a _image. Es eso importante? – Pol

+0

Porque ya tengo una imagen de campo en la base de datos. – Pol

+0

Ok lo resolví con db_column = 'image'. ¡Pero el acero no funciona! – Pol

1

Consulta la base de datos para un registro existente con la misma PK. Compare los tamaños de archivo y las sumas de comprobación de las imágenes nuevas y existentes para ver si son las mismas.

5

Puede proporcionar un argumento adicional para confirmar que se ha publicado una nueva imagen.
Algo así 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 variable de petición

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á su guardar cuando se le llama simplemente.

Usted puede poner esto en su admin.py por lo que este trabajo con el sitio de administración también (para el segundo de 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 
+0

útil dime que: 'WSGIRequest' objeto no tiene atributo 'ARCHIVO' – Pol

+0

Si lo pones en administrador como dijiste ... – Pol

+0

sry sus ARCHIVOS en lugar de ARCHIVO, actualizados para request.FILES.get ('imagen', False) en lugar de request.FILES ['image'], esto evitará la excepción – crodjer

11

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 añadido un cheque para 'imagen' en form.changed_data. Esto supone que estás usando el sitio de administración para actualizar tus imágenes. También tendrá que anular el método predeterminado save_model como se indica a continuación.

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

Creo que tienes razón ... suponiendo que esté usando el sitio de administración, puede anular el save_model en su modelo de administración para pasar el formulario y guardarlo, y verificar si está 'en la imagen' form.changed_data. Lo actualizaré tan pronto como tenga tiempo. – dgraves

+0

Esto solo funciona si el objeto es nuevo como dices. Si carga una nueva imagen, no se disparará el cambio de escala. – Jonathan

+1

"self.pk is None" no funciona si uno especifica el id, entonces: Model.objects.get_or_create (id = 234, ...) no funcionará en esta solución – nuts

2

Lo que hice para lograr el objetivo era hacer esto ..

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

y por debajo del método save() es la siguiente ..

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

así que cuando puedo editar algunos campos pero no edita la imagen, puse esto ..

Model.save("skip creating photo thumbnail") 

puede reemplazar el "skip creating photo thumbnail" con "im just editing the description" o un texto más formal.

Espero que este ayude!

0

En la nueva versión es la siguiente:

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 
Cuestiones relacionadas