A
A
Alexander Vinogradov2019-02-15 07:37:29
Django
Alexander Vinogradov, 2019-02-15 07:37:29

How to upload multiple files from a form in DJANGO?

There is such a question in the toaster, but there is no solution. I know
the example from the link .
The questions are:

  • what is the correct model for uploading many files for one contact?
  • how to load the resulting list of files correctly?

For now, the last option was the following.
model.py
from django.db import models

class Contact(models.Model):
    name = models.CharField(max_length=50, verbose_name='Имя')
    phone = models.CharField(max_length=50, verbose_name='Телефон')
    email = models.EmailField(max_length=50, blank=True, verbose_name='email')
    body = models.TextField(verbose_name='Текст сообщения')

    class Meta:
        verbose_name = "Контакт"
        verbose_name_plural = "Контакты"

    def __str__(self):
        return "{} {}".format(self.name, self.phone)

class Files(models.Model):
    file = models.FileField(upload_to='contact', blank=True, null=True, verbose_name='Файл')
    contact = models.ForeignKey(Contact, blank=True, null=True, on_delete=models.CASCADE)

    class Meta:
        verbose_name = "Файлы"
        verbose_name_plural = "Файлы"

    def __str__(self):
        return self.file

forms.py
from django import forms

from .models import Contact

class ContactForm(forms.ModelForm):

    # files = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

    class Meta:
        model = Contact
        fields = ('name', 'phone', 'email', 'body')
        # widgets = {
        #     'files': forms.ClearableFileInput(attrs={'multiple': True}),
        # }

view.py
from django.views.generic.edit import FormView
from .forms import ContactForm
from pprint import pprint

class ContactView(FormView):
    form_class = ContactForm
    template_name = 'contact.html'
    success_url = '#' # адрес страницы успеха отправки формы

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist('files')
        if form.is_valid():
            pprint(files)
            # for f in files:
                # ...  # Do something with each file.
            return self.form_valid(form)
        else:
            return self.form_invalid(form)


Also, the catch in the last version is that I took out the file field in a separate model. How to include a field with a file in one form? Create another form class with a file and inherit the form from contacts?
_____________________
Thank you!

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexander Vinogradov, 2019-02-16
@ruchej

I made this decision for this issue. The basis was to take an example from the documentation .
The essence of the decision.
There are two models: one is the fields for the contact form, the second is the storage of files.
In the forms.py file, we write a class based on the contact model. Add the files field with multiload properties.
In the view, we get a list of files files = request.FILES.getlist('files') . After checking the correctness of filling out the form if form.is_valid() , we save the content to the database and get the id of this entry id = form.save().pk . Next, we get the contact object according to the received id - contact = Contact.objects.get(pk=id). For this object, we write the resulting files in a loop fl = Files(contact=contact, file = f) .

models.py
from django.db import models


class Contact(models.Model):

    name = models.CharField(max_length=50, verbose_name='Имя')
    phone = models.CharField(max_length=50, verbose_name='Телефон')
    email = models.EmailField(max_length=50, blank=True, verbose_name='email')
    body = models.TextField(verbose_name='Текст сообщения')

    class Meta:
        verbose_name = "Контакт"
        verbose_name_plural = "Контакты"

    def __str__(self):
        return "{} {}".format(self.name, self.phone)



class Files(models.Model):

    file = models.FileField(upload_to='contact', blank=True, null=True, verbose_name='Файл')
    contact = models.ForeignKey(Contact, blank=True, null=True, on_delete=models.CASCADE)

    class Meta:
        verbose_name = "Файлы"
        verbose_name_plural = "Файлы"

    def __str__(self):
        return self.file.name

view.py
from django.views.generic.edit import FormView
from .forms import ContactForm
from .models import Contact, Files
import pdb # pdb.set_trace()

class ContactView(FormView):
    form_class = ContactForm
    template_name = 'contact.html'
    success_url = '#' # адрес страницы успеха отправки формы

    def post(self, request, *args, **kwargs):
        form_class = self.get_form_class()
        form = self.get_form(form_class)
        files = request.FILES.getlist('files')
        if form.is_valid():
            id = form.save().pk
            contact = Contact.objects.get(pk=id)
            if files:
                for f in files:
                    fl = Files(contact=contact, file = f)
                    fl.save()
            return self.form_valid(form)
        else:
            return self.form_invalid(form)

forms.py
from django import forms

from .models import Contact


class ContactForm(forms.ModelForm):

    files = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}), required=False)

    class Meta:
        model = Contact
        fields = ('name', 'phone', 'email', 'body')

A
Astrohas, 2019-02-15
@Astrohas

https://docs.djangoproject.com/en/2.1/topics/forms... use formsets.

S
ShipOmsk, 2021-10-20
@ShipOmsk

Try widget:
forms.py
....
class FileFieldForm(forms.Form):
file_field = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question