Django & AJAX combined - javascript

;0mage to process it on server and get a response without refreshing the page. I look up for some tutorials how to use AJAX and jQuery to do this but I don't have much knowledge at this matter. I'm completly stuck and have no idea what shall I do next. So far my code looks like this:
models.py
class Snip(models.Model):
#some fields
snip = models.FileField(upload_to="snips/")
latex = models.TextField(default = '')
forms.py
from .models import Snip
from django import forms
class SnipForm(forms.ModelForm):
class Meta:
model = Snip
fields = ['snip']
HTML:
<form id="snipForm" method="POST" enctype="multipart/form-data">
<input type="hidden" name="csrfmiddlewaretoken" value="...">
<div class="row align-items-center">
<div class="col-12">
<label for="id_snip">Snip:</label>
<input type="file" name="snip" required="" id="id_snip" class="btn-success p-2 rounded">
<input type="submit" name="upload" id="upload" class="btn btn-secondary">
</div>
</div>
</form>
JavaScript/AJAX
var upload_btn = document.getElementById("upload")
upload_btn.addEventListener('click', function () {
var form_data = new FormData();
var ins = document.getElementById('id_snip').files.length; //
if(ins == 0) return console.log("No snip!!!")
form_data.append("file[]", snip.files[0]);
csrf_token = $('input[name="csrfmiddlewaretoken"]').val();
form_data.append("csrfmiddlewaretoken", csrf_token);
headers = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest'};
console.log(form_data);
console.log(headers);
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');
}
});
$.ajax({
type: 'POST',
url: 'https://localhost:8000/docs/', // point to server-side URL
dataType: "json",
ContentType: "application/json",
cache: false,
processData: false,
headers: headers,
data: form_data,
success: function (response) { // display success response
console.log("SUCCESSSSSSSSS")
},
error: function (response) {
console.log("NOPEEEEEE")
}
});
});
views.py
from django.shortcuts import render
from django.contrib.auth.models import User
from .models import Snip
from .forms import SnipForm
from django.http import JsonResponse
from django.core import serializers
def generate(request):
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
if is_ajax and request.method == "POST":
file = request.FILES['snip']
processed_image = "Some text from OCR"
return JsonResponse({'text':'Yay, I got text from OCR'})
if request.method == 'GET':
Users = User.objects.all()
form = SnipForm()
user_list = []
for user in Users:
if user.get_full_name():
user_list.append(user.get_full_name())
return render(request, "new.html", {'Users': user_list, 'form': form})
To sum up:
The image is loaded to id_snip input tag. After clicking on id="upload" button it should be sent to django server and then to outer OCR API to receive some text back. Then it's supposed to be displayed on the front end without refreshing the page. However after clicking submit I get error:
The view docs.views.generate didn't return an HttpResponse object. It returned None instead.
My first thought was to check the is_ajax value. It occured to be false. So my question is:
How can I check if the request "is AJAX"? I know in previous versions of django it was is_ajax() method but since some like 3.1 version is not recommended
Is there any simple way to do it? My goal is to put received response (text) somewhere else on the page.
#UPDATE:
So I changed a bit of JavaScript/AJAX code above due to this post
I added
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest');
}
});
However on Django error page I can't see any META info such as HTTP_X_REQUESTED_WITH.
What more it seems that no data is appended to the form_data:
Output of:
console.log(form_data)
console.log(headers)
is:
FormData {}
{HTTP_X_REQUESTED_WITH: 'XMLHttpRequest'}
For now I get exactly the same error message, which is The view docs.views.generate didn't return an HttpResponse object. It returned None instead.
What might be wrong with this code? It seems fine for me

Related

Ajax call run by form submission and will pass data to a separate views.py template

I am building a web application using Django. I have a search function on my index page. When a user submits the form an AJAX call should be executed. This AJAX call should take all the needed data from the form and pass it over to a completely separate views.py template that will make API GET requests using that data and build a new page using that separate template.
As of right now it is not loading the separate views.py template, I am unsure if I am passing the data correctly however I do see /searchresults?searchType=data1&executeLocation=data2 in my console because my AJAX call is returning on success currently. It is safe to assume that I have all the data needed in the data1 and data2 variables, I just need help redirecting to the new page and passing the data along with the redirect.
My code:
urls.py
# The home page
path('', views.index, name='home'),
# Search results page
path('searchresults', views.search_results, name='searchresults'),
AJAX
function getSearchResults(searchType,executeLocation,csrf_token)
{
$.ajax(
{
type: $(this).attr('method'),
url: "searchresults", //The URL you defined in urls.py
data :
{
searchType: searchType,
executeLocation: executeLocation,
csrfmiddlewaretoken: csrf_token
},
dataType: 'text',
success: function(response) // currently executes success (but not correct outcome)
{
console.log(response);
alert('winner winner chicken dinner');
},
error: function(response)
{
console.log(response);
alert('failure');
}
}).done(function(data)
{
console.log(data)
});
}
index.html
<form method="POST" action="{% url 'searchresults'%}">
...
<button type="submit" onclick="getSearchResults('data1','data2','{{csrf_token}}')">Submit</button>
</form>
views.py
def search_results(request):
context = {}
context['requestData'] = request.POST
html_template = loader.get_template('search/searchresults.html')
return HttpResponseRedirect(html_template.render(context, request))
An acceptable solution should be able to do the following tasks:
Redirect the user to the search_results page
Pass the form data to the search_results page somehow
After assistance from #AminMir I was able to get a working solution. It turns out I do not need AJAX but I did need a forms.py file.
view.py
def index(request):
context = {'segment': 'index'}
context['SearchForm'] = SearchForm()
return HttpResponse(html_template.render(context, request))
forms.py
from django import forms
class SearchForm(forms.Form):
searchType = forms.CharField(max_length = 100)
executedLocation = forms.CharField(max_length = 100)
searchValue = forms.CharField(max_length = 100)
index.html
<form method="POST" action="{% url 'searchresults'%}">
{% csrf_token %}
{{ SearchForm.as_ul }}
<input type="submit" value="submit">Search</button>
</form>
This form will then post my data to my views.py for my search_result page which is left unchanged.

Django: Ajax not receiving data from server response

I am pretty new to Django and I am trying to figure out how to add content dynamically coming from a python script without reloading a page.
Currently, I have two functions in my views.py file. One handles uploading a file (home), and the other handles calling a python script and handling the file (handle). The reason I separated it like this is because I want to sequentially populate a HTML table as the python script works with the uploaded file.
However, my ajax function is not receiving any data from the handle function's http response and I am not sure why. Neither the success nor the error functions are being called. This is really strange because the print statement in the handle function in views.py prints successfully with data.
Views.py
i=0
uploaded_file = None
def home(request):
if (request.method == 'POST'):
file_form = UploadFileForm(request.POST, request.FILES)
if file_form.is_valid():
global uploaded_file
uploaded_file = request.FILES['file']
print(uploaded_file)
else:
file_form = UploadFileForm()
return render(request, 'personal/home.html', {'form': file_form})
def handle(request):
# TODO make ajax wait for a response from 'home'
# so I don't have to wait for 1 second
time.sleep(1)
data = {}
data['Name'] = fileName(uploaded_file)
if(request.is_ajax()):
print(data) # prints succesfully
return HttpResponse(json.dumps(data),
content_type="application/json")
home.html
<script type = "text/javascript" language = "javascript">
function post_tables(data) {
alert(data)
}
$(document).ready(function(post_tables) {
$("#upload").click(function(event){
$.ajax( {
contentType: "application/json; charset=utf-8",
dataType: "json",
type: "get",
url:'/handler',
success: function(data) {
console.log("over here")
post_tables(data)
},
error: function(data) {
console.log("down here")
post_tables("error being thrown")
}
});
});
});
</script>
urls.py
urlpatterns = [
path(r'', views.home, name='home'),
path(r'handler', views.handle, name='handle'),
]
I explained the whole process ajax django to you. Perhaps your problem will be solved. good luck.
views.py
def handle(request):
if request.method == 'POST':
data = request.POST
field_example = data.get('field_example')
return JsonResponse(data)
else:
data = request.GET
field_example = data.get('field_example')
return JsonResponse(data)
home.html
<form id="upload">
{% csrf_token %}
<input type="text" name=field_example>
.
.
.
</form>
urls.py
urlpatterns = [
path(r'', views.home, name='home'),
path(r'handler/', views.handle, name='handle'),
]
js code in home.html:
$("#upload").submit(function (e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: "{% url 'handle' %}",
type: 'GET',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (data) {
console.log("over here")
post_tables(data)
},
error: function (data) {
console.log("down here")
post_tables("error being thrown")
}
});
});

Django POST With Using Ajax

I have one app name register_login and this app manages login and register opeartions. I have a form on localhost:8000/login page and i want that the button redirects to my func in register_login app but i cant do it. I'm new at Django Framework. How can i handle this?
MAIN URLS.PY
from django.conf.urls import include,url
from django.contrib import admin
from register_login.views import login, register, test
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^homepage/', include('homepage.urls')),
url(r'^login/$', login),
url(r'^register/$', register),
url(r'^success/$', test),
]
LOGIN PAGE .HTML
<form id=registerLogin style="margin-top: 30px; margin-left: 350px;">
<header>Login</header>
<label >Username <span>*</span></label>
<input id="username"/>
<label >Password <span>*</span></label>
<input id="password"/>
<button id="login">Login</button>
<h1 style="margin-left: 20px;">Are you not registered?</h1>
<button id="register">Register</button>
</form>
At the end of this html there is my .js file. I didnt forget.
JAVASCRIPT
if (!jQuery) { throw new Error("This page requires jQuery") }
function readInput() {
e.preventDefault();
var userName = document.getElementById('username').value;
var password = document.getElementById('password').value;
debugger
$.ajax({
type: "POST",
url: "/success/",
data: {'username':username,'password':password, csrfmiddlewaretoken: '{{ csrf_token }}'},
dataType: 'json',
success : function(json) {
$('#post-text').val(''); // remove the value from the input
console.log(json); // log the returned json to the console
console.log("success"); // another sanity check
},
});
}
(function ($) {
$("#login").click(function(){
readInput();
});
})(jQuery);
And finally my function. Its in register_login app as i said before
REGISTER_LOGIN VIEW
def test(request):
embed()
if request.method == 'POST':
embed()
return HttpResponse("hell world")
I tried to change url like "/register_login/success/","/register_login/success","/register_login/success/$","/success/","success/" or "/success/$". Nothing works
I need to go that function but it doesnt :(
Since you are logging in via ajax, you can not redirect in your test view. What you can do is add a redirect in your ajax success function. Something like this:
// similar behavior as an HTTP redirect
window.location.replace("/some-url/");
or
// similar behavior as clicking on a link
window.location.href = "/some-url/";
Also, you need to fix your javascript code, add preventDefault in the click handler and remove it in the readInput. You also need to remove the quotes in the data object and make sure you used the correct variables. Something like this:
$(function() {
function readInput() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
$.ajax({
type: "POST",
url: "/success/",
data: {
username: username,
password: password,
csrfmiddlewaretoken: '{{ csrf_token }}'
},
dataType: 'json',
success : function(json) {
window.location.replace("/some-url/");
}
});
}
$("#login").click(function(e){
e.preventDefault();
readInput();
});
});

Normal form submitting correctly but ajax form submits null

I have developed a super simple REST API in Flask using Flask-RESTful for development purposes. It takes text from a POST method and returns json data with the submitted text.
The code for the API:
api.py
from flask import Flask, request
from flask_restful import Resource, Api, reqparse
from flask_cors import CORS, cross_origin
app = Flask(__name__)
api = Api(app)
CORS(app)
class APITest(Resource):
parser = reqparse.RequestParser()
parser.add_argument('text')
def get(self):
return {'message': 'welcome to the api!'}
def post(self):
args = self.parser.parse_args()
_text = args['text']
return {'text': _text}
api.add_resource(APITest, '/api')
if __name__ == '__main__':
app.run(debug=True)
Now, the following HTML works completely fine and I get the response I'm looking for with no errors:
index.html
<form method="post" action="http://localhost:5000/api">
<input type="text" name="text" id="text-input">
<input type="submit" value="Send!">
</form>
returns: { 'text': 'whatever text i submitted' }
If I try to do the exact same thing, but with AJAX, I get a different result:
index.html
...
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script src="submit.js"</script>
...
<form>
<input type="text" name="text" id="text-input">
<input type="submit" value="Send!">
</form>
submit.js
$("form").submit((e) => {
e.preventDefault();
var fd = new FormData()
fd.append('text', $('#text-input').val())
$.ajax({
url: 'http://localhost:5000/api',
type: 'POST',
data: fd,
processData: false
});
return false;
})
returns {'text': null}
Things I've tried
replacing ${'text-input').val() with document.getElementById('text-input').value
various different ways of sending "form data" including var fd = { text: ${'text-input').val() }
One thing you can try is just grabbing the form data using jquery rather than building it yourself. Example:
<form id="respond_form" enctype="multipart/form-data">
<input type="text" name="text" id="text-input">
<input type="file" name="fl" id="fl">
<input type="submit" value="Send!">
</form>
$("#respond_form").submit((e) => {
e.preventDefault();
var form_data = new FormData();
var file_data = $("#fl").prop("files")[0];
form_data.append("file", file_data)
$.ajax({
url: 'http://localhost:5000/api',
type: 'POST',
data: form_data,
processData: false
});
return false;
})

how to upload file on django server using javascript/jQuery and ajax

After having spent hours, I need help to match the javascript code to the django codes.
I am using the "minimal-django-file-upload-example" version django 1.8 from the git https://github.com/axelpale/minimal-django-file-upload-example.
In standalone, it works very well.
Now i try to upload file from javascript and i do not succeed to make it works.
Javascript Code
function UploadBlob(zip)
{
var ZipFileBlob = zip.generate({type:"blob"});
var fd = new FormData();
fd.append('data', ZipFileBlob);
fd.append('fname', 'ZipOfImage.zip');
fd.append('enctype','multipart/form-
$.ajaxSetup({
type: 'POST',
url: 'http://127.0.0.1:8000/myapp/list/',
enctype: "multipart/form-data",
headers: { "X-CSRFToken": getCookie("csrftoken") }
});
$.ajax({
data: fd,
processData: false,
contentType: false
}).done(function(data) {console.log(data);});
}
Django code
in forms.py
class DocumentForm(forms.
docfile = forms.FileField(label='Select a file')
in views.py
def list(request):
# Handle file upload
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
newdoc = Document(docfile = request.FILES['docfile'])
newdoc.save()
# Redirect to the document list after POST
return HttpResponseRedirect(reverse('myproject.myapp.views.list'))
else:
print "invalid form"
else:
form = DocumentForm() # A empty, unbound form
# Load documents for the list page
documents = Document.objects.all()
# Render list page with the documents and the form
return render_to_response(
'list.html',
{'documents': documents, 'form': form},
context_instance=RequestContext(request)
)
The code run up to the request.method == 'POST'. After, i do not know if i should add field to the ajax requests (and which ones) or if there is a more suitable form in django or do something else.
Please help!

Categories