How do I upload a file using ajax with django? - javascript

I'm new to this. Could you show me how to send a file to server using ajax. I could submit to my server a String, but I don't know how would ajax handle a File?
upload_stuff.js
$(document).on('submit', '#CustomerRequest', function(e){
e.preventDefault();
$.ajax({
type:'POST',
url:'/create_request',
data:{
ajax_file1:$('#html_file1').val(),
ajax_file2:$('#html_file2').val(),
ajax_file2:$('#html_file3').val(),
...
view.py
def create_request (request):
if request.method == "POST":
server_file1 = request.FILES('ajax_files1')
server_file2 = request.FILES('ajax_file2')
server_file3 = request.FILES('ajax_file3')
I do have csrf_token and and enctype="multipart/form-data" on my html form

I have tried this and it works fine, Hope it works for you too.
First create a relevant form in your forms.py file which would look like this:
from django import forms
class FileForm(forms.Form):
file = forms.FileField(required=True)
In your html file it would look like:
<div>
<form id="file_form" action="/application/new_file/" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label class="btn btn-info btn-xs" for="subgroup_file" style="background-color: #042d63;border-color: #dddddd;border-width: 2px;color: white;padding: 5px 21px;" id="send_file" data-toggle="tooltip" data-placement="auto top" title="Choose The File">
<input id="the_file" name="file" type="file" style="display:none;">
<span class="glyphicon glyphicon-paperclip"></span>
</label>
<input type="submit" id="file_form_submit" class="my-small-btn" value="Submit" data-toggle="tooltip" data-placement="auto top" title="Submit File">
</form>
</div>
then the id=file_form can trigger this:
$('#file_form').submit(function(event){
event.preventDefault();
var formData = new FormData(this); //get data of form elements for submission
formData.append('sg_id', '{{ sg_id }}'); //add additional data to form's data
$.ajax({
url: "/application/new_file/",
type: "POST",
enctype: 'multipart/form-data',
data: formData,
processData: false,
contentType: false,
cache: false,
success: function (data) {
if(! data.created){
location.reload();
} else if(! data.valid_extension){
swal({
title: 'You can only submit PDF files',
text: '',
icon: 'error',
timer: 5000,
});
}
}
});
});
Here I have also added a sweet alert which informs the user he/she is only allowed to upload PDF files. The URL finally takes you from urls.py to a fucntion named saveFile in views.py which would something like this:
def saveFile(request):
if(request.user != AnonymousUser()):
try:
if request.method == 'POST':
file_form = FileForm(request.POST, request.FILES)
sg_id = request.POST.get("sg_id")
subgroup = SubGroup.objects.get(pk=sg_id)
if(file_form.is_valid()):
file = file_form.cleaned_data["file"]
name = str(file)
f, extension = os.path.splitext(name)
if(extension in valid_extensions):
obj = Files.objects.create(
file = file,
subgroup = subgroup,
creator = request.user,
created_at = datetime.datetime.now(),
name = name
)
.......
.......
.......
The SubGroup and Files are objects defined in models.py which connect you to the database.

i don't know if this might be helpful or not, but in JQuery the $('#fileinput').val() doesn't return "Ajax friendly" file data, try using document.getElementById('fileinput').files[0]; to get the file data using raw javascript and try to add these options on the ajax request
contentType: false,
processData: false,

Related

Append File to Form before Submit HTML and PHP

I have an application that I am building. The app creates a json file, then a jar file is uploaded and the json file is inserted into the jar, and the new jar is returned.
I have created a basic HTML form and PHP file that currently works, but the user must select both the jar and the json file to upload. I need to modify this now so that the user chooses the zip file, but the form would select the JSON from the JS.
THE HTML:
<form id="jar-form">
<div class="mb-3">
<label for="test-jar-upload" class="form-label">Select Jar File Files:</label>
<input type="file" id="test-jar-upload" name="jar" accept=".jar" class="form-control">
</div>
<div class="mb-3">
<button type="button" class="btn btn-primary" ng-click="export.exTest()" name="upload_file">Submit</button>
</div>
THE JS:
$scope.export.exTest = function(){
console.log('New Manual Submit');
let formData = new FormData();
let tFile = new Blob([JSON.stringify($scope.export.file)], {type: 'application/json'});
formData.append('jar',document.getElementById('test-jar-upload').files[0]);
formData.append('desc',tFile);
$scope.newData = formData;
$.ajax({
url: './assets/api/test.php',
data: formData,
type: "POST",
contentType: false,
processData: false
})
}
The AJAX call was taken from another answer, but doesn't successfully open the test.php file. If I change the path, I do get a 404 error returned.

Formdata is showing file but laravel's Request is showing null

I have a form in datatable as follows.
<form method="post" enctype="multipart/form-data">
<label for="file_'+row["course_id"]+'">
<i class="far fa-2x fa-file-pdf f-gray"></i>
</label>
<input type="file" id="file_'+row["course_id"]+'">
</form>
This shows a pdf button inside datatable for file upload. Onclick it will show a file browser for file selection.
Using javascript's FormData() I am passing the file to Laravel controller.
$(document).on("change", "[id^=file_]", function(e) {
var file_data = this.files[0];
var form_data = new FormData();
form_data.append("pdf_file", file_data);
$.ajax({
url: "/pdfUpload",
cache: false,
processData: false,
data: form_data,
type: 'post',
success: function(data) {
$('div.flash-message').html(data).fadeOut(5000);
}
});
});
The request headers is as follows:
But the following code says there is no file and is returning null.
public function upload(\Google_Service_Drive $service, Request $request){
if ($request->hasFile('pdf_file')) {
dump('yes');
}else{
dump('no');
}
dd($request->pdf_file);
$data = file_get_contents(?)
}
Output:
Any help on what I'm missing here?
Also, I need to get $data = file_get_contents(?) working. What should I pass here

Sending image from Form in FormData with Ajax doesn't appear on server side (Flask python)

I want to create Bootstrap Modal that has a form with textarea and image, and send that to the server.
My form on modal looks like this:
<form id="formData" method="POST" enctype="multipart/form-data">
<fieldset class="form-group">
<div class="form-group">
<textarea class="form-control" id="content" name="content" required></textarea>
</div>
<div class="form-group">
<label for="image">Got any photo?</label>
<input class="form-control-file" id="image" name="image" type="file">
</div>
</fieldset>
<button class="btn purple-btn-outline-modal" type="submit">Add</button>
</form>
The AJAX I'm using:
var form = document.forms.namedItem("formData");
form.addEventListener('submit', function (ev) {
var oData = new FormData(form);
oData.append('image', $('#image')[0].files[0])
for (var p of oData) {
console.log(p); // <- logs image in oData correctly
}
$.ajax({
url: '/test/',
type: 'POST',
method: 'POST',
data: oData,
enctype: 'multipart/form-data',
cache: false,
contentType: false,
processData: false,
success: function (data) {
},
});
ev.preventDefault();
}, false);
But on the server side (Python Flask) the image is not in request form:
#main.route('/test/', methods=['POST'])
def test():
if request.method == 'POST':
app.logger.debug(request.form) # ImmutableMultiDict([('content', 'my sent content')])
app.logger.debug(request.form['content']) # 'my sent content'
app.logger.debug(request.form['image']) # <- KeyError: 'image'
return jsonify(...)
What is wrong?
SOLVED.
Solution by #v25:
request.files['image']
worked.

Why this 2 form dosn't work with ajax in Django?

I am developing an application on django, and faced with strange problems with Ajax. On my website 4 forms should be processed using Ajax. And two of them work great. But 2 others not heard
about Ajax at all. Consider working and non-working forms.
views.py
view working form
def login_user(request):
form = LoginForm(request.POST)
context = { 'form': form, }
if request.method == 'POST' and form.is_valid():
username = form.cleaned_data['user_login']
password = form.cleaned_data['user_password']
user = authenticate(username=username, password=password)
response_data = {}
if user and user.is_active:
login(request, user)
response_data['result'] = 'Ok'
else:
response_data['result'] = 'Bad'
return HttpResponse(json.dumps(response_data))
else:
return redirect('index')
view non-working form
def add_new_station(request, add_station_slug):
form = AddStationForm(request.POST)
myuser = get_object_or_404(User, id=request.user.id)
print(request.user)
if request.method == 'POST' and form.is_valid():
response_data = {}
UserStation.objects.create(
station=Station.objects.get(slug=add_station_slug),
impressions=form.cleaned_data['impressions'],
list=UserStationsList.objects.get(user=myuser)
response_data['result'] = 'Ok'
)
return HttpResponse(json.dumps(response_data))
else:
return redirect('index')
urls.py
urlpatterns = [
path('', index, name='index'),
path("add-in-list/<str:add_station_slug>/", add_new_station, name='new_station'),
path('login/', login_user, name='login_action'),
...
]
html
html working form
<form id="login_form" action="{% url 'login_action' %}" method="post">
{% csrf_token %}
{{ formlogin }}
<div class="text-center">
<button type="submit" class="btn btn-dark mt-2">Entry</button>
</div>
</form>
html non-working form
<form id="add_station_form" action="{% url 'new_station' choice_station.slug %}" method="post">
{% csrf_token %}
{{ formaddstaion }}
<div class="text-center">
<button type="submit" class="btn btn-outline-success mt-2">I visited this station</button>
</div>
</form>
mian.js
script working form
$('#login_form').submit(function() {
$.ajax({
data: $(this).serialize(),
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {
data = JSON.parse(response)
if (data['result'] === "Ok"){
$('.login-message').hide()
location.reload()
}
else{
$('.login-message').show(100).html('wrong data')
}
}
});
return false;
});
script non-working form
$('#add_station_form').submit(function() {
$.ajax({
type: $(this).attr('method'),
url: $(this).attr('action'),
success: function(response) {
data = JSON.parse(response)
alert('data') // try check, but ajax don't reach here
}
});
return false;
});
In the first case, everything works perfectly, in the second, the Ajax does not start at all (I’m just being redirect to the page with HttpResponce. So, what is the problem?
In the second form you are trying to send a POST request to a Django view using ajax but as we all know POST requests don't contain parameter inside the url so you need to remove the parameter from the url and do some necessary changes like the following:
Remove the parameter in your url and add a hidden input field to your form which will contain the parameter.
<form id="add_station_form" action="{% url 'new_station' %}" method="post">
{% csrf_token %}
{{ formaddstaion }}
<input type="hidden" name="add_station_slug" value="{{choice_station.slug}}" readonly>
<div class="text-center">
<button type="submit" class="btn btn-outline-success mt-2">
I visited this station
</button>
</div>
</form>
Inside an ajax as #Borut said in comments you need to pass the data to your ajax request like this:
$.ajax({
type: $(this).attr('method'),
url: $(this).attr('action'),
data: $(this).serialize(),
success: function(data) { alert(data.response); }
});
Now inside the urls.py remove the parameter like this:
urlpatterns = [
...
path("add-in-list/", add_new_station, name='new_station'),
...
]
Now at last inside the views you can extract your parameter and use it:
from django.http import JsonResponse
# from Django 1.7 onward you should use JsonResponse instead of HttpResponse
# so that you don’t need to serialize the data before returning the response object.
def add_new_station(request):
response_data = {'response': 'Something went wrong!'}
form = AddStationForm(request.POST)
myuser = get_object_or_404(User, id=request.user.id)
if request.method == 'POST' and form.is_valid():
slug = request.POST.get('add_station_slug')
UserStation.objects.create(
station=Station.objects.get(slug=slug),
impressions=form.cleaned_data['impressions'],
list=UserStationsList.objects.get(user=myuser)
)
response_data['response'] = 'UserStation Created Successfully!'
return JsonResponse(response_data)

What about Dropzone.js within an existing form submitted by AJAX?

Ok, here is the scenario. I have already a form having some input fields, some radio buttons and an input type=file. There is a button for submitting the whole form using AJAX.
Everything was working fine, until i decided to change the input type=file with the more fancy DropZone.js
Now i have the following html code (a sample here):
<form enctype="multipart/form-data" id="test_form" name="test_form" class="form uniformForm">
<input class="form-control" type="text" value="" name="a-name" id="a-name" />
<label for="a-name">Field Name</label>
<div class="dropzone dropzone-previews" id="my-awesome-dropzone </div>
</form>
<button class="btn btn-primary btn-large" id="submitForm"> Submit </button>
I have the following js (jQuery), too:
$("button#submitForm").click(function(){
var fd = new FormData(document.getElementById("test_form"));
fd.append("label", "WEBUPLOAD");
$.ajax({
type: "POST",
url: "create_form.php",
data: fd,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
});
});
$("div#my-awesome-dropzone").dropzone({
url: "#",
paramName: "creative_file",
maxFilesize: 1,
autoProcessQueue: false
});
In documentation of Dropzone.js says that the dropzone div looks like <input type="file" name="file" />. The only difference is that i want to rename the input name as creative_file.
I have 2 question.
1) This doesn't work. When pressing the Submit button, i have FIREBUG opened and i check what it sends as POST. It sends everything except the files. No creative_file, no file at all.
2) If finally figured out how to make it works, is there any way to have a fallback with this implementation especially for the iOS or Android devices ?
1)
$("#salvar").on('click',function(e) {
if ($("#psl_titulo").val() == "") {
alert('Empty');
} else {
e.preventDefault();
if (myDropzone.getQueuedFiles().length > 0) {
myDropzone.processQueue();
} else {
$("#my-awesome-dropzone").submit(function(e)
{
var postData = $(this).serializeArray();
var formURL = $(this).attr("action");
$.ajax(
{
url : formURL,
type: "POST",
data : postData,
success:function(data, textStatus, jqXHR)
{
window.location.href = url_redirect;
},
error: function(jqXHR, textStatus, errorThrown)
{
alert('Ocorreu um erro ao salvar ao enviar os dados. Erro: ' + textStatus);
}
});
e.preventDefault();
});
$("#my-awesome-dropzone").submit();
}
}
});

Categories

Resources