【问题标题】:How to show only one image in Django admin inline如何在 Django 管理内联中仅显示一张图像
【发布时间】:2012-04-20 03:57:14
【问题描述】:

我在我的一个应用中使用django.contrib.admin

我的模型:

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

我的admin.py:

class ImageInline(admin.StackedInline):
    model           = Image

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

在管理部分,我现在可以创建图库并在同一页面上添加图像。默认情况下,django 显示三种图像上传表单。我怎样才能将其更改为只有一个?

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

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

    在我看来,要使包含图像的内联有用,您需要实际显示内联图像(因此自定义覆盖图像小部件):

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

    注意:这会做一些你可能不喜欢的调整大小的事情 - 所以你可能需要自己重写小部件的拇指大小部分。

    那么您将需要覆盖内联表单中的小部件:

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

    你最终会得到这样的东西(这是另一个项目的一部分,有很多额外的东西):

    【讨论】:

      【解决方案2】:

      查看InlineModelAdmin.extraInlineModelAdmin.max_num 的文档。

      我相信在你的情况下max_num 需要为 1 和 extra 0。

      【讨论】:

        【解决方案3】:

        如果你使用sorl-thumbnails,小部件是这样的:

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

        【讨论】:

          猜你喜欢
          • 2017-10-16
          • 1970-01-01
          • 2011-01-27
          • 1970-01-01
          • 2014-07-17
          • 1970-01-01
          • 1970-01-01
          • 2021-11-30
          • 1970-01-01
          相关资源
          最近更新 更多