4

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 视频,我应该编写自己的小部件来显示视频并将其应用于一些假字段吗?

对于不必要的假字段,通过小部件解决这个问题很奇怪。还是正常方式?

任何帮助将不胜感激!谢谢!

4

1 回答 1

2

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

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

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

于 2009-05-26T18:19:43.373 回答