Djangoの複数のファイルまたは複数の画像を処理できるモデルフィールドはありますか?または、ManyToManyFieldを画像またはファイルを含む別のモデルにする方がよいでしょうか。
Django-adminのアップロードインターフェースを備えたソリューションが必要です。
2017年以降の人のために、 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)
Djangoに同梱されている複数の画像を保存する方法を知っている単一のフィールドはありません。アップロードされたファイルはモデルにファイルパス文字列として保存されるため、Pythonに変換する方法を知っているのは基本的にCharField
です。
典型的な複数の画像の関係は、ProductImage -> Product
などの関連するモデルを指すFKを持つ個別の画像モデルとして構築されます。
この設定により、Django adminにInline
として非常に簡単に追加できます。
M2Mフィールドは、GalleryImages
が1つ以上のGallery
オブジェクトから参照されているという、本当に多対多の関係である場合に意味があります。
既存のシステムで単一のファイルから複数のファイルに変更する必要があり、少し調査した結果、これを使用することになりました: https://github.com/bartTC/Django-attachments
カスタムメソッドが必要な場合は、モデルを簡単にサブクラス化できるはずです。
1つのモデルの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 から取得したこの回答コード