Django 多文件字段
Posted
技术标签:
【中文标题】Django 多文件字段【英文标题】:Django Multiple File Field 【发布时间】:2012-07-16 18:30:09 【问题描述】:是否有可以为 django 处理多个文件或多个图像的模型字段?还是将 ManyToManyField 设置为包含图像或文件的单独模型更好?
我需要一个在 django-admin 中带有上传界面的解决方案。
【问题讨论】:
模型字段不用于上传。您是希望将这些文件/图像存储在数据库中还是通过浏览器上传? 将它们存储在数据库中,与单个文件字段基本相同但可以对其进行迭代 【参考方案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 张图片上传到相册时)以上是关于Django 多文件字段的主要内容,如果未能解决你的问题,请参考以下文章