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?
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.
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):
Check the docs for InlineModelAdmin.extra and InlineModelAdmin.max_num.
I believe in your case max_num
needs to be 1 and extra
0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With