I'm using django.contrib.admin
in one of my apps.
我在我的一个应用程序中使用django.contrib.admin。
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
:
我的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?
在管理部分,我现在可以创建一个库并在同一页面上添加图像。默认情况下,django显示三种图像上传形式。如何将其更改为仅一个?
3 个解决方案
#1
19
Check the docs for InlineModelAdmin.extra and InlineModelAdmin.max_num.
检查InlineModelAdmin.extra和InlineModelAdmin.max_num的文档。
I believe in your case max_num
needs to be 1 and extra
0.
我相信你的情况max_num需要1和0。
#2
24
extra = 0
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):
你最终得到像这样的东西(这是另一个项目的一部分,并有一堆额外的东西):
#3
5
In case if you use sorl-thumbnails , widget is like this:
如果你使用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
...
#1
19
Check the docs for InlineModelAdmin.extra and InlineModelAdmin.max_num.
检查InlineModelAdmin.extra和InlineModelAdmin.max_num的文档。
I believe in your case max_num
needs to be 1 and extra
0.
我相信你的情况max_num需要1和0。
#2
24
extra = 0
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):
你最终得到像这样的东西(这是另一个项目的一部分,并有一堆额外的东西):
#3
5
In case if you use sorl-thumbnails , widget is like this:
如果你使用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
...