ManyToMany关系的管理内联表单中的图像和视频预览

时间:2009-05-25 15:55:16

标签: django django-admin django-forms

A有3个模型:具有ManyToManyField关系的项目,图像和视频:

class Project(models.Model):
    images = models.ManyToManyField('Image', through='Project_Images')
    video = models.ManyToManyField('Video', through='Project_Video')

class Image(models.Model):
    original = models.ImageField()
    projects = models.ManyToManyField('Project', through='Project_Images')

class Video(models.Model):
    projects = models.ManyToManyField('Project', through='Project_Video')

我使用链接到当前项目的图像和视频的内嵌形式配置项目的管理表单:

class ProjectAdmin(admin.ModelAdmin):
    inlines = [VideoInline, ImagesInline]

class ImagesInline(admin.TabularInline):    
    model = Project_Images
    raw_id_fields = ['project','image']

class VideoInline(admin.TabularInline):    
    model = Project_Video
    raw_id_fields = ['project','video']

但是带有简单选择字段和删除复选框的内联表对我来说非常悲惨,我想在这里显示图像或视频(youtube)的预览。我在AdminImageWidget的帮助下解决了这个问题:

class ImageForm(forms.ModelForm):
    class Meta:
        model = Image

    preview = forms.ImageField(widget=AdminImageWidget())
    def __init__(self, *args, **kwargs):
        super(ImageForm, self).__init__(*args, **kwargs)
        try:
            image = Image.objects.get(id=self.instance.image_id)
            self.fields["preview"].initial = image.original
        except:
            pass

class ImagesInline(admin.TabularInline):
    .....
    form = ImageForm

这是最好的方法吗?在我的情况下,我不需要文件上传输入,只需要内联表格中的图像预览。我还需要预览youtube视频,我应该编写自己的小部件来显示视频并将其应用到一些假的视野吗?

通过小部件为不必要的伪字段解决这个问题很奇怪。或者这是正常的方式吗?

非常感谢任何帮助! 谢谢!

1 个答案:

答案 0 :(得分:2)

您应该创建一个类似于AdminImageWidget的小部件,但它只显示图像,而不是上传框。要应用该小部件,您不需要自定义Form类或伪字段,只需在ImageInline上使用formfield_overrides:

class ImageInline(admin.TabularInline):
    ...
    formfield_overrides = { models.ImageField: {'widget': YourPreviewWidget}}

编辑:糟糕,没有完全处理ManyToManyField问题 - 您正在显示“直通”表的内联,而不是具有实际ImageFields的表。鉴于此,你现在所做的可能不是一个糟糕的解决方案。我能想到的另一种选择是为Select编写一个专门的替换小部件,它知道如何显示当前所选Image对象的选择框和预览图像。这样你就可以避免需要假的额外字段。