Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show only one image in Django admin inline

Tags:

I'm using django.contrib.admin in one of my apps.

my models:

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') 

my admin.py:

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

In the admin section I'm now able to create a gallery and add images on the same page. By default django shows three image upload forms. How can I change it to only one?

like image 586
jarred Avatar asked Apr 06 '12 14:04

jarred


People also ask

What is Django admin site?

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.


2 Answers

extra = 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', ] 

And in my opinion, for a inline that has images to be useful you need to actually display the image inline (so custom override the image widget):

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)) 

Note: that this does some resizey stuff you may not like - so you may need to rewrite the thumb sizing part of the widget yourself.

so then you are going to need to override the widget in your inline's form:

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

and you end up with somethig like this (this is part of another project and has a bunch of extra stuff): screenshot of the image admin inline

like image 196
Francis Yaconiello Avatar answered Sep 28 '22 06:09

Francis Yaconiello


Check the docs for InlineModelAdmin.extra and InlineModelAdmin.max_num.

I believe in your case max_num needs to be 1 and extra 0.

like image 39
arie Avatar answered Sep 28 '22 08:09

arie