Django - ImageField с несколькими изображениями
У меня есть модель, в которой есть поле ImageField. Я хочу, чтобы пользователи могли загружать несколько изображений для объекта модели - не только одно изображение. Как это можно сделать? С помощью поля изображения или с помощью другого подхода.
Вы не можете хранить несколько изображений в одном поле ImageField.
Одним из решений этой проблемы может быть создание дополнительной модели (я назвал ее "Attachment" для своего проекта социальной сети, называйте свою модель так, как вам удобно), которая будет ссылаться на исходную модель по внешнему ключу. Таким образом, вы сможете загружать сколько угодно изображений и создавать экземпляр этой новой модели для каждого нового изображения.
Пример модели вложения:
class Attachment(DatetimeCreatedMixin, AuthorMixin):
class AttachmentType(models.TextChoices):
PHOTO = "Photo", _("Photo")
VIDEO = "Video", _("Video")
file = models.ImageField('Attachment', upload_to='attachments/')
file_type = models.CharField('File type', choices=AttachmentType.choices, max_length=10)
publication = models.ForeignKey(TheOriginalModelYouUsedImageFieldIn, on_delete=models.CASCADE, verbose_name='Model that uses the image field')
class Meta:
verbose_name = 'Attachment'
verbose_name_plural = 'Attachments'
Вы можете хранить несколько изображений в одном поле в модели продукта django.
Подробная логика состоит в том, чтобы создать поле формы модели, которое позволяет выбирать загрузку нескольких файлов, затем загрузить эти изображения (в моем случае я загрузил их в cloudinary, поскольку я уже настроил cloudinary для обработки всех моих загрузок файлов в моем проекте django), затем получить урлы этих изображений и присвоить их одному полю в экземпляре модели, чтобы вы всегда могли получить это поле и получить урлы для ваших изображений.
Вот фрагмент кода моей текущей реализации, чтобы помочь вам
Допустим, у меня есть Product
Model
class Product(models.Model):
#your other fields
multiview_images = models.TextField(blank=True,null=True)
#other fields
def get_multiview_images_list(self):
if self.multiview_images:
try:
urls = json.loads(self.multiview_images)
return [ {url} for url in urls]
except json.JSONDecodeError as e:
print("JSON Decode Error:", e)
return []
def set_multiview_images(self, images):
self.multiview_images = json.dumps(images)
productmodelform.py
class ProductModelForm(forms.ModelForm):
files = MultiFileField(min_num=1, max_num=10)
class Meta:
model = Product
fields = '__all__'
def save(self, commit=True):
instance = super().save(commit=False)
files = self.cleaned_data['files']
multiview_images = []
for file in files:
cloudinary_url = cloudinary.uploader.upload(file)['url']
print(cloudinary_url)
multiview_images.append(cloudinary_url)
instance.multiview_images = json.dumps(multiview_images)
if commit:
instance.save()
return instance
admin.py
class ProductAdmin(admin.ModelAdmin):
list_display = [field.name for field in Product._meta.fields]
form = ProductModelForm
admin.site.register(Product, ProductAdmin)
Поле modelform создаст кнопку множественной загрузки, которая позволит вам загрузить несколько файлов из вашего локального хранилища, затем загрузит их в cloudinary и вернет урлы каждого из изображений в виде списка в поле images в модели продукта, который будет сохранен как список или массив урлов в поле images.
При api вызове конечной точки продукта поле get_multiview_images_list будет выглядеть следующим образом (не забудьте добавить его в список полей в serializers.py)
[
[url1],
[url2],
[url3],
[url10]
]
Обратите внимание, что эта реализация работает только при загрузке из админ-панели django. Вы всегда можете установить ограничение на максимальное и минимальное количество загрузок в productmodelform.