Ajax Post Request isn´t working in django - django

I have a problem with django. I have researched so much on other questions but their answers don´t work for me. I need to send a base64 string of an image to my view so that i can store the string instead of the image in my database. So, I want to send data via ajax to my django view. Due to whatever reason, the form gets already submitted by django automatically and i tried to stop it, but then ajax isn´t firing too. I would really appreciate help because it already has cost me so much time.
add.html
<form method="post" enctype="multipart/form-data" onsubmit="submitdata()">
{% csrf_token %}
<input type="text" name="dish" required id="id_dish" placeholder="Rezeptname">
<img ><input type="file" name="image" required id="id_image" accept="image/*">
<div class="image-upload"><img id="img_id" src="#">
</div><button type="submit">Upload</button>
</form>
<script>
function submitdata() {
$.ajax({
type: "POST",
contentType: "application/json",
url: "/add",
data: JSON.stringify({
csrfmiddlewaretoken: document.getElementsByName("csrftoken")[0].value,
"dish": "test",
"image": dataurl,
"recipe": document.getElementsByName("recipe")[0].value,
"caption": document.getElementsByName("caption")[0].value
}),
dataType: "json",
});
}
</script>
views.py
#login_required(login_url="login")
def add(response):
if response.method == "POST":
form = AddForm(response.POST, response.FILES)
if form.is_valid():
print(response.POST)
# The print statement prints the data from the automatical form
submit, not from the ajax submit
current_user = Client.objects.get(id=response.user.id)
current_user.post_set.create(poster=response.user.username,
dish=form.cleaned_data.get("dish"),
image=response.POST.get("image"),
caption=form.cleaned_data.get("caption"),
recipe=form.cleaned_data.get("recipe"))
messages.success(response, "You successfully added a post.")
return redirect("home")
else:
form = AddForm()
return render(response, "main/add.html", {"form":form})
urls.py
urlpatterns = [
path("add", views.add, name="add")
]
forms.py
class AddForm(forms.ModelForm):
dish = forms.CharField()
image = forms.FileField()
caption = forms.TextInput()
recipe = forms.TextInput()
class Meta:
model = Post
fields = ["dish", "image", "recipe", "caption"]

When you use the onsubmit property and want to prevent the form from sending data, make sure the handler returns false.
If the onsubmit handler returns false, the elements of the form are not submitted. If the handler returns any other value or returns nothing, the form is submitted normally.
<script>
function submitdata() {
$.ajax({
type: "POST",
contentType: "application/json",
url: "/add",
data: JSON.stringify({
"dish": "test",
"image": dataurl,
"recipe": document.getElementsByName("recipe")[0].value,
"caption": document.getElementsByName("caption")[0].value
}),
dataType: "json",
//return false if ajax is successful
// you can also do something with response data if needed
success: function(data) {return false;},
//return false if ajax request returns error
error: function(data) {return false;},
});
}
</script>

Related

How to get the checked objects in django view with ajax?

I am very new to ajax. Here I have a django form and inside the form there is a form group of checkbox.
What I want here is, from the checkbox if the user check some user object I want to get it in the django view immediately before the form submit. And if the the user uncheck this It should be removed from django view also. How can I do this ?
After form submit it works fine but I want to get the checked user before the form submits.So I think in this case ajax will be required. But I am very beginner in ajax so I got stuck here.
template
<div class="form-group">
<div class="checkbox">
<input class="checkbox1" name="users" type="checkbox" value="{{user.pk}}"
id="user{{user.pk}}"/>
<label for="user{{user.pk}}"></label>
</div>
</div>
jquery
<script>
$(function(){
var checked_lists = [];
$(".checkbox1:checked").each(function() {
checked_list.push(this.value);
});
$.ajax({
url: "{% url 'my_url' %}",
data:{
checked_Lists: checked_list,
}
}
});
});
</script>
views
print(self.request.POST.getlist('checked_lists'))
In you case you need to pass checked_list[] javascript list to view so need ajax
for that
and handle ajax request base on checkbox change event
<script>
$('.checkbox1').change(function(){ // checkbox1 change event
var checked_lists = [];
$(".checkbox1:checked").each(function() {
checked_list.push(this.value);
});
var formdata = new FormData();
$.ajax({
formdata.append('checked_list',checked_list)
formdata.append('csrfmiddlewaretoken',$('input[type=hidden]').val());
$.ajax({
url:"/profile_upload", //replace with you url
method:'POST',
data:formdata,
enctype: 'application/x-www-form-urlencoded',
processData:false,
contentType:false,
success:function(data){
alert("Display return data"+data)
},
error:function(error){
alert(error.error)
}
});
});
});
</script>
views.py :You define view base on your logic
def <view-name>(request):
if request.method=='POST':
user_list = request.getlist('checked_list')
return JsonResponse(status=200,data={'data':'success'})
else:
return JsonResponse(status=203,data={'error':'unauthorize request.!!'})
If you use post request to define csrf_token so pass them if your script
code in single page formdata.append('csrfmiddlewaretoken',{% csrf_token %});through those link and do
Ajax Request For Sumbit Data
if you get error on it, let me know

getting undefined after ajax get call to fetch from postgres db in django

I am trying to fetch data from postgres table by clicking a button in the django template page and the fetched data from db should be populated into another div.
For the same, I am using Ajax get call to fetch the data from DB, but I am facing problem that the value is shown as undefined.
With the Ajax call if I populate the target div with the below, it is working.
$('#childContainer').html(10 + Math.floor(Math.random()*91));
But when I try to fetch the data from table, I am getting undefined.
Here is the code which I have written:-
views.py:-
def index(request):
distinctenvapp = Env_app.objects.values('environment_name').distinct()
return render(request, 'envconfigmgmt/index.html', {'distinctenvapp' : distinctenvapp});
def get(self,request, *args, **kwargs):
if self.request.is_ajax():
return self.ajax(request)
def ajax(self, request):
response_dict= {
'success': True,
}
action = request.GET.get('action','')
if action == 'get_appnames':
env_id = request.GET.get('id','')
if hasattr(self, action):
response_dict = getattr(self, action)(request)
envappname = Env_app.objects.get(environment_name='env_id')
response_dict = {
'application_name':envappname.application_name
}
return HttpResponse(simplejson.dumps(response_dict),
mimetype='application/json')
index.html:-
<div><center><table id="t1"><tr>
{% for obj in distinctenvapp %}
<td>
<button id="{{ obj.environment_name }}">
{{ obj.environment_name }}
</button>
</td>
{% endfor %}
</tr></table></center></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("button").click(function(){
$env_id = $(this).attr('id')
$.ajax({
type: "GET",
data: { action: "get_appnames", id: $env_id },
success: function(data){
$("#childContainer").html("<strong>"+data.application_name+"</strong>");
console.log(data);
}
});
//$('#childContainer').html(10 + Math.floor(Math.random()*91));
});
});
</script>
<div id="childContainer"></div>
I expect the data to be fetched in the target child div.
It should show application names like App1, App2 etc, but it is showing undefined.
IF your ajax request returning JSON content then you have to define datatype in Ajax parameter
$.ajax({
type: "GET",
data: { action: "get_appnames", id: $env_id },
dataType: 'json',
success: function(data){
$("#childContainer").html("<strong>"+data.application_name+"</strong>");
console.log(data);
}
});
For more refere this https://api.jquery.com/jquery.ajax/
I think your ajax request doesnt have url so ajax called current page again
current page is a string and doesnt have application_name
be aware that the mimetype argument was removed in Django 1.7. Use content_type instead.

Unable to print the variable passed from view to template

I am trying to pass the variable ,I am obtaining from view to the template but it is showing in the preview of the web-browser(chrome) but not on actual screen.
Following is my view file:
analyzer=SentimentIntensityAnalyzer()
data={}
with open('today_5th_oct_new.csv','r',newline='', encoding='utf-8') as f:
reader = csv.reader(f)
for row in reader:
data[row[0]]=float(row[1])
analyzer.lexicon.update(data)
def index(request):
return render(request, "gui/index.html")
#csrf_exempt
def output(request):
sentences = request.POST.get('name',None)
senti = analyzer.polarity_scores(sentences)
context_dict = {'sentiment': senti}
return render(request,"gui/index.html", context = context_dict)
Following is my template-
<!doctype html>
<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
<body>
<form action>
Enter Sentence:<input id = "name" type = "text" name = "EnterSentence" encoding = "utf-8"><br>
<input onclick = "testfunction()" type = "button" value = "Submit" >
</form>
<div><strong>Score is {{ sentiment }}</strong></div>
</body>
<script>
var testfunction = () => {
var test = document.getElementById("name").value
console.log(test)
$.ajax({
type: "POST",
dataType: "json",
url: 'output/',
data:{
csrfmiddlewaretoken: '{{ csrf_token }}',
'name': test
},
success: function(response) {
console.log("Succesful return firm ajax call");
},
error: function(result){
console.log("Failure");
}
});
}
</script>
I am observing the desired output in preview but not on actual page.
How to resolve that ?
You're getting the response via Ajax but you're not doing anything with it. Your success function needs to insert the content into the page somehow.
To be honest, I don't see why you use Ajax here at all; if you removed the JS code and just let your form do a POST directly it would work fine.

Django: How to upload a file using ajax

I am using django 1.5, python 2.7 and jquery 1.9. I have a form which has precisely 2 fields i.e. title and document. When I press submit I want the users chosen document to be present in the request.FILES as shown in the view.
When I submit the regular form (without ajax), this works fine, but with ajax I do not get the file field in my request. Any suggestions on how to upload a file using ajax.
HTML:
<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
{% csrf_token %}
<ul>
<li>
<div>Title</div>
<input id="title" type="text" maxlength="200"/>
<div class="error"></div>
</li>
<li>
<div>Upload File</div>
<input id="document" type="file" size="15" />
<div class="error"></div>
</li>
</ul>
<input type="submit" value="submit"/></p>
</form>
FORMS.PY:
class UploadForm( forms.Form ):
document = forms.FileField()
title = forms.CharField(max_length = 200)
def clean(self):
cleaned_data = super(UploadForm, self).clean()
return cleaned_data
def save(self, *args, **kwargs):
title = self.cleaned_data['title']
doc = self.cleaned_data['document']
document = Document(title = title, document = doc)
document.save()
return document
SCRIPT:
<script type="text/javascript">
$("#uploadForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
});
</script>
VIEWs.PY
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
The answer to that question is not that simple. First of all if you intend to support old browsers then indeed it gets nasty. You have to deal with hidden iframes and some JavaScript tricks. I do advice using some well-known scripts for that like jQuery-File-Upload.
But the world is evolving and new technologies arise including HTML5. There's a new File API which is available in most modern browsers ( IE10+, FireFox3.6+, Chrome13+, see: http://caniuse.com/fileapi ) which can be used for that. First you need some HTML:
<input type="file" id="file-select" />
Then you can bind to (for example) change event:
$('#file-select').change( handleFileSelect );
and finally the handler itself:
var data = {};
function createReaderHandler(name) {
return function(ev) {
data[name] = ev.target.result;
};
}
function handleFileSelect(ev) {
var files = ev.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var file = files[i],
name = file.name || file.fileName,
reader = new FileReader();
reader.onload = createReaderHandler(name);
reader.readAsText(file);
}
}
Once the data is loaded into JavaScript memory (note that the operation is asynchronous) you can send it via AJAX like any other data. There are more options: depending on your file you can read it as a binary data using .readAsBinaryString and so on. Google is your friend. :)
Also I think there already are good scripts for uploading files with a fallback to old methods. This one can be interesting (haven't tried it):
http://www.plupload.com/
I think the issue is in the submit button, change it into normal button
ie, <button type='button' id='submit'>submit</button>(by default all buttons in form are submit)
and the ajax as
$('#submit').on('click',function(){
frm = $(this).parents('form')
$.ajax({
type: frm.attr('method'),
dataType:'json',
url: frm.attr('action'),
data: frm.serialize(),
async: false,
success: function (data) {
console.log('success')
},
error: function(data) {
console.log("Something went wrong!");
}
})
All others will be same
Just try it will work

Data not sent using jquery .ajax() to a Django view

I am trying to create a single ajax call. The ajax call is sent to server but the data then I am sending is not available in the request object in the view. When I print request.post, it gives <QueryDict: {}>. No data is being sent to the server. I know that the browser is sending the data since I can view it in the request payload in chrome.
script:
$("#chatform").submit(function(e) {
e.preventDefault();
//serialText = $(this).serialize();
var userText = $("#usertext").val();
var xmlRequest = $.ajax({
type: "POST",
url: "/sendmessage/",
data: {'tosend': userText},
//dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(data){
appendMessageSent(data.messagesent);
}
});
});
view.py:
def send_message(request):
if request.is_ajax():
message = "The hell with the world"
print request.POST
json = simplejson.dumps(
{'messagesent' : request.POST['tosend']+"This is how we do it"}
)
return HttpResponse(json, mimetype='application/javascript')
html
<form id="chatform" action="" method="POST" >
<input type='hidden' name='csrfmiddlewaretoken' value='8idtqZb4Ovy6eshUtrAiYwtUBboW0PpZ' />
<input type="text" name="chatarea" id="usertext"/>
<input type="submit" value="Send">
</form>
I get an error saying that key tosend is not found in request.post dict.
MultiValueDictKeyError: "Key 'tosend' not found in <QueryDict: {}>
Can any one tell me why the data is not being sent to the server and/or why I can't access it in my view?
To make form data appear in request.POST, use contentType: "application/x-www-form-urlencoded".
If you use application/json, you have to parse the raw data yourself (request.raw_post_data in django <1.4, request.body in django >=1.4):
def send_message(request):
if request.is_ajax():
message = "The hell with the world"
data = json.loads(request.body)
result = json.dumps({'messagesent' : data['tosend'] + "This is how we do it"})
return HttpResponse(result, mimetype='application/javascript')