2009-12-09 17 views
18

Vedo un sacco di persone con le app Django che hanno il caricamento delle immagini che stanno ridimensionando automaticamente le immagini dopo che sono state caricate. Va bene e bene per alcuni casi, ma non voglio farlo. Invece, voglio semplicemente costringere l'utente a caricare un file che è già della dimensione corretta.Convalida la dimensione dell'immagine nell'amministratore di django

Desidero avere un ImageField in cui forzare l'utente a caricare un'immagine che è 100x200. Se l'immagine che caricano non è esattamente quella dimensione, voglio che il modulo di amministrazione non venga restituito come non valido. Mi piacerebbe anche essere in grado di fare la stessa cosa per i rapporti di aspetto. Voglio forzare l'utente a caricare un'immagine 16: 9 e rifiutare qualsiasi caricamento non conforme.

So già come ottenere la larghezza e l'altezza dell'immagine, ma non posso farlo sul lato server fino a dopo che l'immagine è già stata caricata e il modulo è stato inviato correttamente. Come posso controllarlo prima, se possibile?

risposta

45

Il posto giusto per farlo è durante la convalida del modulo.
Un esempio veloce (redigerà/integrate con ulteriori informazioni più avanti):

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

ero troppo lento, ecco il link correlato: http://docs.djangoproject.com/en/dev/ref/forms/validation/# clean-a-specific-field-attribute – monkut

+1

Mentre questa soluzione è utile come riferimento, l'OP ha dichiarato che desidera verificare le dimensioni dell'immagine PRIMA dell'invio del modulo. Quindi deve essere qualcosa di lato client. O sto fraintendendo il suo ultimo paragrafo? – cethegeek

+0

Non intendo necessariamente prima dell'invio del modulo, purché sia ​​prima che il modello venga salvato. – Apreche

0

Questa può essere una vittima di/molto simile a questa domanda:

Using jQuery, Restricting File Size Before Uploading

Non credo c'è un modo per farlo nel modo desiderato. soluzione Agos è la strada da percorrere ...

Edit: Una delle risposte nelle legate domanda SO parla di utilizzare il flash per farlo. Quindi, mentre può essere possibile fare con qualche altra tecnologia, non penso che tu possa farlo con un javascript dritto.

+0

Un'altra possibile tecnologia potrebbe essere un'applet Java. Ho visto un certo numero di caricatori affrontare la questione in questo modo. È anche utile nel caso in cui si desideri effettivamente consentire un numero elevato di caricamenti. – Agos

2

uso questa funzione nel vostro file di modello,

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

Questo non funziona. Facendo riferimento al file in questo modo da un validatore, prima che il file sia stato salvato, restituisce semplicemente '*** FileNotFoundError: [Errno 2] Nessun file o directory di questo tipo: '/ srv/www/media/80329e39-5c5c-4e79- 8e32-51087ae00f6a''. Forse funzionerebbe con i file che Django non salva come oggetti 'InMemoryUploadedFile', dove sono in'/tmp' o in qualche posto simile come un vero file. Non l'ho provato, comunque. – Bryson

Problemi correlati