2012-04-06 18 views
19

Estoy usando django.contrib.admin en una de mis aplicaciones.Django admin inline

mis modelos:

class Gallery(models.Model): 
    location = models.ForeignKey(Location) 
    date = models.CharField(max_length = 15) 

class Image(models.Model): 
    gallery = models.ForeignKey(Gallery) 
    name = models.CharField(max_length=35) 
    image = ImageField(upload_to='songs') 

mi admin.py:

class ImageInline(admin.StackedInline): 
    model   = Image 

class GalleryAdmin(admin.ModelAdmin): 
    inlines = [ ImageInline, ] 

En la sección de administración ahora soy capaz de crear una galería y añadir imágenes en la misma página. De forma predeterminada, django muestra tres formularios de carga de imágenes. ¿Cómo puedo cambiarlo a solo uno?

Respuesta

24

adicional = 0

class GalleryImageInline(admin.TabularInline): 
    """ 
    Gallery Image inline 
    """ 
    fieldsets = (
     (
      None, 
      { 
       'fields': ('name', 'image',) 
      } 
     ), 
    ) 

    model = Image 
    extra = 0 


class GalleryAdmin(admin.ModelAdmin): 
    """ 
    Case Study Admin 
    """ 
    fieldsets = (
     (
      None, 
      { 
       'fields': ('location', 'date',) 
      } 
     ), 
    ) 

    inlines = (GalleryImageInline,) 
    list_display = ['location', 'date'] 
    list_filter = ['location', ] 

Y en mi opinión, para una línea que tiene imágenes para ser útil, necesita en realidad mostrar la imagen en línea (por lo anular encargo el widget de imagen):

from django.contrib.admin.widgets import AdminFileWidget 
from django.utils.translation import ugettext as _ 
from django.utils.safestring import mark_safe 
import os 
import Image 

class AdminImageWidget(AdminFileWidget): 
    def render(self, name, value, attrs=None): 
     output = [] 
     if value and getattr(value, "url", None): 

      image_url = value.url 
      file_name=str(value) 

      # defining the size 
      size='100x100' 
      x, y = [int(x) for x in size.split('x')] 
      try : 
       # defining the filename and the miniature filename 
       filehead, filetail = os.path.split(value.path) 
       basename, format = os.path.splitext(filetail) 
       miniature   = basename + '_' + size + format 
       filename   = value.path 
       miniature_filename = os.path.join(filehead, miniature) 
       filehead, filetail = os.path.split(value.url) 
       miniature_url  = filehead + '/' + miniature 

       # make sure that the thumbnail is a version of the current original sized image 
       if os.path.exists(miniature_filename) and os.path.getmtime(filename) > os.path.getmtime(miniature_filename): 
        os.unlink(miniature_filename) 

       # if the image wasn't already resized, resize it 
       if not os.path.exists(miniature_filename): 
        image = Image.open(filename) 
        image.thumbnail([x, y], Image.ANTIALIAS) 
        try: 
         image.save(miniature_filename, image.format, quality=100, optimize=1) 
        except: 
         image.save(miniature_filename, image.format, quality=100) 

       output.append(u' <div><a href="%s" target="_blank"><img src="%s" alt="%s" /></a></div> %s ' % \ 
       (miniature_url, miniature_url, miniature_filename, _('Change:'))) 
      except: 
       pass 
     output.append(super(AdminFileWidget, self).render(name, value, attrs)) 
     return mark_safe(u''.join(output)) 

Nota: que este hace algunas cosas resizey no le guste - lo que puede tener para volver a escribir la parte de tamaño del pulgar del widget usted mismo.

así, entonces van a tener que anular el widget en forma de su línea:

class GalleryImageForm(forms.ModelForm): 
    """ 
    Image Admin Form 
    """ 
    class Meta: 
     model = Image 
     widgets = { 
      'image' : AdminImageWidget, 
     } 

class GalleryImageInline(admin.TabularInline): 
    ... 
    form = GalleryImageForm 
    ... 

y se termina con somethig así (esto es parte de otro proyecto y tiene un montón de material extra) : screenshot of the image admin inline

5

En caso si usted utiliza sorl-thumbnails, widget es así:

from django.contrib.admin.widgets import AdminFileWidget 
from django.utils.safestring import mark_safe 
from sorl import thumbnail 


class AdminImageWidget(AdminFileWidget): 
    def render(self, name, value, attrs=None): 
     output = [] 
     if value and getattr(value, "url", None): 
      t = thumbnail.get_thumbnail(value,'100x100') 
      output.append('<img src="{}">'.format(t.url)) 
     output.append(super(AdminFileWidget, self).render(name, value, attrs)) 
     return mark_safe(u''.join(output)) 


class GalleryImageForm(forms.ModelForm): 
    """ 
    Image Admin Form 
    """ 
    class Meta: 
     model = Image 
     widgets = { 
      'image' : AdminImageWidget, 
     } 

class GalleryImageInline(admin.TabularInline): 
    ... 
    form = GalleryImageForm 
    ...