web-dev-qa-db-ja.com

Django複数のファイルフィールド

Djangoの複数のファイルまたは複数の画像を処理できるモデルフィールドはありますか?または、ManyToManyFieldを画像またはファイルを含む別のモデルにする方がよいでしょうか。

Django-adminのアップロードインターフェースを備えたソリューションが必要です。

22
Dave

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)
14
MrKsn

Djangoに同梱されている複数の画像を保存する方法を知っている単一のフィールドはありません。アップロードされたファイルはモデルにファイルパス文字列として保存されるため、Pythonに変換する方法を知っているのは基本的にCharFieldです。

典型的な複数の画像の関係は、ProductImage -> Productなどの関連するモデルを指すFKを持つ個別の画像モデルとして構築されます。

この設定により、Django adminにInlineとして非常に簡単に追加できます。

M2Mフィールドは、GalleryImagesが1つ以上のGalleryオブジェクトから参照されているという、本当に多対多の関係である場合に意味があります。

既存のシステムで単一のファイルから複数のファイルに変更する必要があり、少し調査した結果、これを使用することになりました: https://github.com/bartTC/Django-attachments

カスタムメソッドが必要な場合は、モデルを簡単にサブクラス化できるはずです。

4
PhoebeB

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 から取得したこの回答コード

1
Tarek Kalaji