2009-12-09 17 views
18

Veo mucha gente con aplicaciones Django que tienen cargas de imágenes que redimensionan automáticamente las imágenes después de que se cargan. Eso está bien y bien para algunos casos, pero no quiero hacer esto. En cambio, simplemente quiero forzar al usuario a cargar un archivo que ya tiene el tamaño adecuado.Validar el tamaño de la imagen en django admin

Quiero tener un ImageField donde obligo al usuario a cargar una imagen que es 100x200. Si la imagen que cargan no es exactamente de ese tamaño, quiero que el formulario de administrador no sea válido. También me gustaría poder hacer lo mismo para las relaciones de aspecto. Quiero forzar al usuario a cargar una imagen que sea 16: 9 y rechazar cualquier carga que no se ajuste.

Ya sé cómo obtener el ancho y el alto de la imagen, pero no puedo hacerlo desde el lado del servidor hasta que la imagen ya esté cargada, y el formulario se envíe correctamente. ¿Cómo puedo verificar esto antes, si es posible?

Respuesta

45

El lugar correcto para hacerlo es durante la validación del formulario.
Un ejemplo rápido (editará/integrarse con más información más adelante):

from django.core.files.images import get_image_dimensions 
from django.contrib import admin 
from django import forms 

class myForm(forms.ModelForm): 
    class Meta: 
     model = myModel 
    def clean_picture(self): 
     picture = self.cleaned_data.get("picture") 
     if not picture: 
      raise forms.ValidationError("No image!") 
     else: 
      w, h = get_image_dimensions(picture) 
      if w != 100: 
       raise forms.ValidationError("The image is %i pixel wide. It's supposed to be 100px" % w) 
      if h != 200: 
       raise forms.ValidationError("The image is %i pixel high. It's supposed to be 200px" % h) 
     return picture 

class MyAdmin(admin.ModelAdmin): 
    form = myForm 

admin.site.register(Example, MyAdmin) 
+0

que era demasiado lento, aquí está el enlace relacionado: http://docs.djangoproject.com/en/dev/ref/forms/validation/# clean-a-specific-field-attribute – monkut

+1

Si bien esta solución es genial para referencia, el OP dijo que quiere verificar las dimensiones de la imagen ANTES de enviar el formulario. Entonces tiene que ser algo del lado del cliente. ¿O estoy malinterpretando su último párrafo? – cethegeek

+0

No me refiero necesariamente a la presentación del formulario, siempre que sea antes de que se guarde el modelo. – Apreche

0

Ésta puede ser una víctima de/muy similar a esta pregunta:

Using jQuery, Restricting File Size Before Uploading

no creo hay una manera de hacerlo de la manera que desee. La solución Agos es el camino a seguir ...

Editar: Una de las respuestas en la pregunta SO relacionada se refiere al uso del flash para hacerlo. Entonces, si bien es posible hacerlo con alguna otra tecnología, no creo que puedas hacerlo con Javascript directo.

+0

Otra tecnología posible podría ser un applet de Java. He visto un buen número de cargadores abordar el asunto de esa manera. También es útil en caso de que realmente desee permitir cargas grandes/suficientes. – Agos

2

uso de esta función en el archivo de modelo,

from django.core.exceptions import ValidationError 

    def validate_image(fieldfile_obj): 
      filesize = fieldfile_obj.file.size 
      megabyte_limit = 2.0 
      if filesize > megabyte_limit*1024*1024: 
       raise ValidationError("Max file size is %sMB" % str(megabyte_limit)) 

    class Company(models.Model): 
     logo = models.ImageField("Logo", upload_to=upload_logo_to,validators=[validate_image], blank=True, null=True,help_text='Maximum file size allowed is 2Mb') 
+0

Esto no funciona. Al hacer referencia al archivo de este modo desde un validador, antes de guardar el archivo, simplemente devuelve '*** FileNotFoundError: [Errno 2] No existe dicho archivo o directorio: '/ srv/www/media/80329e39-5c5c-4e79- 8e32-51087ae00f6a''. Quizás funcione con archivos que Django no guarda como objetos 'InMemoryUploadedFile', donde están en'/tmp' o en algún lugar similar a un archivo real. No he probado eso, sin embargo. – Bryson