Is there a model field that can handle multiple files or multiple images for django? Or is it better to make a ManyToManyField to a separate model containing Images or File
No there isn't a single field that knows how to store multiple images shipped with Django. Uploaded files are stored as file path strings in the model, so it's essentially a CharField
that knows how to be converted to python.
The typical multiple image relationship is built as a separate Image model with an FK pointing to its relevant model, such as ProductImage -> Product
.
This setup makes it very easy to add into the django admin as an Inline
.
An M2M field would make sense if you it's truly a many to many relationship where say GalleryImages
are referenced from 1 or more Gallery
objects.
I had to change from having a single file to multiple files in an existing system and after a bit of research ended up using this: https://github.com/bartTC/django-attachments
It should be easy to subclass the model if you want custom methods.
For guys from 2017 and later, there is a special section in Django docs. My personal solution was this (successfully works in admin):
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)
FilerFileField and FilerImageField in one model:
They are subclasses of django.db.models.ForeignKey, so the same rules apply. The only difference is, that there is no need to declare what model we are referencing (it is always filer.models.File for the FilerFileField and filer.models.Image for the FilerImageField).
Simple example 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)
Multiple image file fields on the same model in models.py:
Note: related_name attribute required, it is just like defining a foreign key relationship.
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")
This answer code taken from django-filer document