【问题标题】:Django Multiple File FieldDjango 多文件字段
【发布时间】:2012-07-16 18:30:09
【问题描述】:

是否有可以为 django 处理多个文件或多个图像的模型字段?还是将 ManyToManyField 设置为包含图像或文件的单独模型更好?

我需要一个在 django-admin 中带有上传界面的解决方案。

【问题讨论】:

  • 模型字段不用于上传。您是希望将这些文件/图像存储在数据库中还是通过浏览器上传?
  • 将它们存储在数据库中,与单个文件字段基本相同但可以对其进行迭代

标签: django file-upload django-models


【解决方案1】:

对于 2017 年及以后的人,有一个 special section in Django docs。我的个人解决方案是这样的(在管理员中成功运行):

class ProductImageForm(forms.ModelForm):
    # this will return only first saved image on save()
    image = forms.ImageField(widget=forms.FileInput(attrs={'multiple': True}), required=True)

    class Meta:
        model = ProductImage
        fields = ['image', 'position']

    def save(self, *args, **kwargs):
        # multiple file upload
        # NB: does not respect 'commit' kwarg
        file_list = natsorted(self.files.getlist('{}-image'.format(self.prefix)), key=lambda file: file.name)

        self.instance.image = file_list[0]
        for file in file_list[1:]:
            ProductImage.objects.create(
                product=self.cleaned_data['product'],
                image=file,
                position=self.cleaned_data['position'],
            )

        return super().save(*args, **kwargs)

【讨论】:

  • 这个 natsorted 是从哪里来的?
  • 找到了,我正在使用你的解决方案,但我在 file_list 上得到了空列表,你覆盖了你的 html 还是什么?
  • 请在该行设置断点并检查self.files 中的内容。事情发生了变化,我只给出了一个想法,您必须测试并了解发生了什么。
  • self.files 已更改...我检查以获取 getlist('images')
  • 您需要使用与模型中的字段相同的表单字段名称,因此如果您的模型有一个名为file 的字段,请不要将表单字段称为files{}-image 中的后缀也需要与您的字段名称匹配。您可能想要使用 ClearableFileInput 小部件,或者,如果在管理员中,请使用 admin.widgets.AdminFileWidget
【解决方案2】:

不,没有一个字段知道如何存储 Django 附带的多个图像。上传的文件在模型中存储为文件路径字符串,所以本质上是一个CharField,知道如何转换成python。

典型的多图像关系构建为一个单独的图像模型,其中一个 FK 指向其相关模型,例如ProductImage -> Product

这种设置可以很容易地以Inline 的形式添加到 django 管理员中。

如果您确实是多对多关系,即从 1 个或多个 Gallery 对象引用 GalleryImages,则 M2M 字段将是有意义的。

【讨论】:

    【解决方案3】:

    我不得不将现有系统中的单个文件更改为多个文件,经过一番研究后最终使用了这个:https://github.com/bartTC/django-attachments

    如果您想要自定义方法,应该很容易对模型进行子类化。

    【讨论】:

      【解决方案4】:

      FilerFileField 和 FilerImageField 在一个模型中:

      它们是 django.db.models.ForeignKey 的子类,因此适用相同的规则。唯一的区别是,不需要声明我们引用的模型(对于 FilerFileField 始终是 filer.models.File,对于 FilerImageField 始终是 filer.models.Image)。

      简单示例models.py:

      from django.db import models
      from filer.fields.image import FilerImageField
      from filer.fields.file import FilerFileField
      
      class Company(models.Model):
          name = models.CharField(max_length=255)
          logo = FilerImageField(null=True, blank=True)
          disclaimer = FilerFileField(null=True, blank=True)
      

      models.py中同一模型上的多个图像文件字段:

      注意:related_name 属性是必需的,就像定义外键关系一样。

      from django.db import models
      from filer.fields.image import FilerImageField
      
      class Book(models.Model):
          title = models.CharField(max_length=255)
          cover = FilerImageField(related_name="book_covers")
          back = FilerImageField(related_name="book_backs")
      

      此答案代码取自django-filer document

      【讨论】:

      • 恐怕您回答的问题与所问的问题相反。 “单个字段但能够遍历它们”,一对多的关系。您提到的是多对一的解决方案。
      • 这绝对不是 Dave 所要求的!他询问了在 django admin 中一次性上传多个文件(例如,当您想将 100 张图片上传到相册时)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 2011-08-10
      • 2020-06-01
      • 2010-12-24
      • 1970-01-01
      • 2018-09-18
      相关资源
      最近更新 更多