Home > Blockchain >  how to upload image correctly. Django
how to upload image correctly. Django

Time:11-28

I am building a Django application (run in local) and I am having headaches about uploading files/pictures. I have read tons of questions/answers everywhere as well as followed the official doc, but somehow I still have problems.

In my models.py:

FuncionarioPathFoto = models.FileField(
        "Foto",
        upload_to = "images/",
        db_column= "FuncionarioPathFoto",
        null= False,
        blank = False
    )

In my views (I'm using inline forms, so the code is big):

def create_funcionario(request):
    if request.method == "GET":
        form = FuncionariosForm
        
        form_funcionarioadicional_factory = inlineformset_factory(Funcionarios, FuncionarioAdicional, form=FuncionarioAdicionalForm, extra=1)
        form_funcionarioaux_factory = inlineformset_factory(Funcionarios, FuncionarioAux, form=FuncionarioAuxForm, extra=1)
        form_funcionarioarquivo_factory = inlineformset_factory(Funcionarios, FuncionarioArquivo, form=FuncionarioArquivoForm, extra=1)
        form_funcionarioadicional = form_funcionarioadicional_factory()
        form_funcionarioaux = form_funcionarioaux_factory()
        form_funcionarioarquivo = form_funcionarioarquivo_factory()
        
        context = {
            'form': form,
            'form_funcionarioadicional': form_funcionarioadicional,
            'form_funcionarioaux': form_funcionarioaux,
            'form_funcionarioarquivo': form_funcionarioarquivo,
        }     
        return render(request, '../templates/funcionarios/form_funcionarios.html', context)
    
    elif request.method == "POST":
        form = FuncionariosForm(request.POST)
        
        form_funcionarioadicional_factory = inlineformset_factory(Funcionarios, FuncionarioAdicional, form=FuncionarioAdicionalForm)
        form_funcionarioaux_factory = inlineformset_factory(Funcionarios, FuncionarioAux, form=FuncionarioAuxForm)
        form_funcionarioarquivo_factory = inlineformset_factory(Funcionarios, FuncionarioArquivo, form=FuncionarioArquivoForm)
        form_funcionarioadicional = form_funcionarioadicional_factory(request.POST)
        form_funcionarioaux = form_funcionarioaux_factory(request.POST)
        form_funcionarioarquivo = form_funcionarioarquivo_factory(request.POST)
        
        if form.is_valid() and form_funcionarioadicional.is_valid() and form_funcionarioaux.is_valid() and form_funcionarioarquivo.is_valid():
            funcionario = form.save()
            form_funcionarioadicional.instance = funcionario
            form_funcionarioaux.instance = funcionario
            form_funcionarioarquivo.instance = funcionario
            form_funcionarioadicional.save()
            form_funcionarioaux.save()
            form_funcionarioarquivo.save() 
            
            
            messages.success(request, "Funcionário adicionado com sucesso!")
            return redirect(reverse('lista_funcionarios'))
        else: 
            context = {
                'form': form,
                'form_funcionarioadicional': form_funcionarioadicional,
                'form_funcionarioaux': form_funcionarioaux,
                'form_funcionarioarquivo': form_funcionarioarquivo,
            }
            
            return render(request, '../templates/funcionarios/form_funcionarios.html', context)

I put this in my urls, and settings: urls:

if settings.DEBUG:
    urlpatterns  = static(
        settings.MEDIA_URL,
        document_root=settings.MEDIA_ROOT,
    )

settings:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

And I already tried to add <form method="POST" enctype="multipart/form-data">

but I was unsuccessful, when submitting my form, that field keeps giving error.

I tried uploading the file via /admin, and it went to the directory correctly with no errors.

what can i try to do to solve it?

CodePudding user response:

Let me explain the process of uploading files with Django with my own method.

If a file is sent to the server, it is kept in request.FILES as temp. You can see it by saying print(request.FILES) .

First, read the temp data and then load it into the relevant directory with the open function in python.

For example

img = request.FILES['img'].read()

print(type(img))

open('mypath/name.png','wb').write(img) # Note if output not bytes change to open mode 'w'

CodePudding user response:

You need to pass request.FILES in form in views.py

form = FuncionariosForm(request.POST,request.FILES)

and also need to pass enctype="multipart/form-data" in html form

<form action="/action_page_binary.asp" method="post" enctype="multipart/form-data">
  <label for="fname">First name:</label>
  <input type="text" id="fname" name="fname"><br><br>
  <label for="lname">Last name:</label>
  <input type="text" id="lname" name="lname"><br><br>
  <input type="submit" value="Submit">
</form>
  • Related