Качване на множество файлове във формата независимо дали са снимки или видео?
Чрез единични полета във вече съществуващия модел не работи, понеже по този начин се качват по една снимка и по едно видео.
Решението е да се направи допълнителен модел .....Media, който се свързва с първия модел. В него се добавя поле file = models.FileField и се оказва, къде ще се качват файловете.
Пример:
Първи модел
django.contrib.auth import get_user_model
from django.db import models
from django.utils import timezone
UserModel = get_user_model()
class Publication(models.Model):
location = models.CharField(
max_length=200,
null=True,
blank=True,
)
description = models.TextField(
null=False,
blank=False,
)
weight_kg = models.FloatField(
null=True,
blank=True,
)
created_at = models.DateTimeField(
default=timezone.now,
)
user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
Втори модел
class PublicationMedia(models.Model):
MEDIA_TYPE_CHOICES = (
('image', 'Image'),
('video', 'Video'),
)
publication = models.ForeignKey(Publication, on_delete=models.CASCADE)
file = models.FileField(upload_to='files/')
media_type = models.CharField(max_length=5, choices=MEDIA_TYPE_CHOICES)
Формата не се променя и не й се добавя допълнителни полета. С добавено допълнително поле не работи, понеже това поле идва от другия модел. Остава си така:
class PublicationBaseForm(forms.ModelForm):
class Meta:
model = Publication
fields = ["location", "description", "weight_kg"]
widgets = {
'location': forms.TextInput(attrs={'placeholder': 'Enter your fishing location'}),
'description': forms.Textarea(attrs={'placeholder': 'Enter a description of your fishing experience'}),
'weight_kg': forms.NumberInput(attrs={'placeholder': 'Enter weight of the fish'}),
}
След което ръчно се добавя полето за качване на файловете в html-a по този начин:
Във view-то в променливата media_files става списък с качените файлове обекти.
Итерира се през всички файлове с for цикъл и се записва всеки един файл в базата свързан с публикацията.
@method_decorator(login_required, name='dispatch')
class PublicationCreateView(views.CreateView):
form_class = PublicationCreateForm
model = Publication
template_name = "publications/publication_create.html"
success_url = reverse_lazy("feed")
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
media_files = self.request.FILES.getlist('media_files') --> списък от фаловете
for file in media_files: --> итерира се
content_type = file.content_type
media_type = 'video' if content_type.startswith('video') else 'image' --> взима се типа на файла
PublicationMedia.objects.create(
publication=self.object,
file=file,
media_type=media_type
) --> създава се обект
return super().form_valid(form)