I am using threading library for a long-running process in Django. When the process is completed, I want to keep updating progress status on the front-end. I am unable to post anything to the ajax.get() from my thread function.
View.py
def upload_handler(request, file_loc, filename):
// do something with uploaded
// I want to notify user that this process is complete via a post
class Uploader(View):
def get(self, request):
file=UploadForm()
return render(request,'template.html',{'form':file}) #,'files':files})
def post(self, request):
file = UploadForm(data=request.POST, files=request.FILES)
if file.is_valid():
x = request.FILES['file']
file.save()
filename = str(request.FILES['file'])
file_loc = os.path.join(BASE_DIR, 'media', 'images', filename)
upload_thread = Thread(target=upload_handler, args=(request, file_loc, filename))
upload_thread.start()
return HttpResponseRedirect(reverse('imageupload'))
urls.py
urlpatterns = [
path('', Uploader.as_view(), name='imageupload'),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
ajax call script
{
$.ajax({
type:"get",
url:"/uploader",
datatype:"json",
success:function(data)
{
console.log(data);
alert("Your file is processed now!");
}
});
}, 1000);
Assume that file uploaded page will remain open till the long process completes.
AJAX option datatype is "json", but the View does not return a "json".
Related
Im having a hard time figuring out how to integrate this ajax request into my view. I'm still learning how to integrate django with ajax requests.
My first question would be: Does the ajax request need to have its own dedicated URL?
In my case I am trying to call it on a button to preform a filter(Preforms a query dependent on what is selected in the template). I have implemented this using just django but it needs to make new request everytime the user preforms a filter which I know is not efficient.
I wrote the most basic function using JQuery to make sure the communication is there. Whenever the user changed the option in the select box it would print the value to the console. As you will see below in the view, I would to call the ajax request inside this view function, if this is possible or the correct way of doing it.
JQuery - Updated
$("#temp").change( function(event) {
var filtered = $(this).val();
console.log($(this).val());
$.ajax({
url : "http://127.0.0.1:8000/req/ajax/",
type : "GET",
data : {
'filtered': filtered
},
dataType: 'json',
success: function(data){
console.log(data)
},
error: function(xhr, errmsg, err){
console.log("error")
console.log(error_data)
}
});
Views.py
def pending_action(request):
requisition_status = ['All', 'Created', 'For Assistance', 'Assistance Complete', 'Assistance Rejected']
FA_status = RequisitionStatus.objects.get(status='For Assistance')
current_status = 'All'
status_list = []
all_status = RequisitionStatus.objects.all()
status_list = [status.status for status in all_status]
# This is where I am handling the filtering currently
if request.GET.get('Filter') in status_list:
user_req_lines_incomplete = RequisitionLine.objects.filter(Q(parent_req__username=request.user) & Q(status__status=request.GET.get('Filter')))
current_status = request.GET.get('Filter')
else:
user_req_lines_incomplete = RequisitionLine.objects.filter(parent_req__username=request.user).exclude(status__status='Completed')
user_reqs = Requisition.objects.filter(par_req_line__in=user_req_lines_incomplete).annotate(aggregated_price=Sum('par_req_line__total_price'),
header_status=Max('par_req_line__status__rating'))
return render(request, 'req/pending_action.html', { 'user_reqs':user_reqs,
'user_req_lines_incomplete':user_req_lines_incomplete,
'requisition_status':requisition_status,
'current_status':current_status,
'FA_status':FA_status})
def filter_status(request):
status = request.GET.get('Filter')
data = {
'filtered': RequisitionLine.objects.filter(Q(parent_req__username=request.user) & Q(status__status=status)),
'current_status': status
}
return JsonResponse(data)
Urls.py
path('pending/', views.pending_action, name='pending_action')
First: you have to divide your template to unchangeable part and the part that you want to modify with your filter.
Second: for your goal you can use render_to_string. See the followning link https://docs.djangoproject.com/en/2.1/topics/templates/#usage
code example (views.py):
cont = {
'request': request, #important key-value
'your_models_instances': your_models_instances
}
html = render_to_string('your_filter_template.html', cont)
return_dict = {'html': html}
return JsonResponse(return_dict)
In your js file you need to determine relative url "{% url 'name in yours url file'%}"
And in success you need to add next line:
success: function(data){
$(".filter-block").html(data.html);
}
i hope it will help you! Good luck!
I have a single view which scrolls through user data. There are next and previous buttons to scroll. When user presses next, ajax sends the user id to the django view and displays the data.
If user clicks the next button two or three times consecutively (which they usually do), the calls get aborted and server is killed.
$("#new").click(function() {
$.ajax({
type:'POST',
url:'/new/',
data:{
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success:searchSuccess,
dataType: 'html'
});
});
function searchSuccess(data, textStatus, jqXHR)
{
$('#myForm').html(data);
}
This is the view.
def master_detail_next(request):
def decrement_voucher_id(form_id):
voucher_id = str(int(form_id) - 1).zfill(4)
return voucher_id
if request.method == 'POST':
form_id = request.POST['voucher_id']
voucher_id = decrement_voucher_id(form_id)
voucher_id = get_decremented_voucher_id(voucher_id)
else:
voucher_id = ''
# Inline forms
author = TmpPlInvoice.objects.get(voucher_id=voucher_id)
author_form = TmpForm(instance=author)
BookFormSet = inlineformset_factory(TmpPlInvoice, TmpPlInvoicedet,
exclude=('emp_id', 'voucher', 'lineitem', 'id',),
form=TmpFormDetForm, )
formset = BookFormSet(instance=author)
totalform = TmpFormTotal(instance=author)
postform = CheckPostedForm(instance=author, posted=author.posted)
return render(request, 'form.html', {'form': author_form, 'formset': formset, 'formtotal': totalform, 'postform': postform})
How can i avoid that? What is that i am doing wrong?
Django 1.7.2/ python 3.4
this code is about 'like'.
if user click the 'like' button, ajax calls 'pushLike'.
if the user has liked the article before(saved inside Mysql), delete the row on table(DB).
or if the user is not liking the article, create a row and insert it on the table(DB).
after that, count how many like has beed clicked on that article.
I would like to pass the likeCnt(count) to ajax, and write it on the button.
The likeCnt has the right value(I checked it on the server mysql table).
The button color does change(white to blue, and vise versa), but the text does not change.
It seems like json does not pass to ajax. I tried passing data by 'text' type and it did worked, but i want it by json.
I've tried simplejson, json, mimetype, content_type on HttpResponse.
please help me.
view
#login_required
def pushLike(request):
pk = request.GET['writing_id']
try:
la = LikeArticles.objects.get(user = User.objects.get(username=request.user.username), article_id=pk)
if(la.is_like()):
la.delete()
likeCnt = LikeArticles.objects.filter(article_id=pk).count()
FreeBoards.objects.filter(id=pk).update(like = likeCnt)
else: #Never happens
la.like = True
la.save()
likeCnt = LikeArticles.objects.filter(article_id=pk).count()
FreeBoards.objects.filter(id=pk).update(like = likeCnt)
except ObjectDoesNotExist:
la = LikeArticles(user = User.objects.get(username=request.user.username),
article = FreeBoards.objects.get(id=pk),
like = True,
)
la.save()
likeCnt = LikeArticles.objects.filter(article_id=pk).count()
FreeBoards.objects.filter(id=pk).update(like = likeCnt)
data = {'likeCnt': likeCnt}
# return render(request, url, context)
return HttpResponse(simplejson.dumps(data), mimetype='application/javascript')
javascript
<script type="text/javascript">
$(document).ready(function(){
$('#btn-like').click(function(){
var e = $('#btn-like').css('background-color');
$.ajax({
url : '/sle/freeboards/pushLike/',
data : {'writing_id':{{writing_id}},
},
dataType : "json",
success:function(data){
alert(data.likeCnt);
if(e == 'rgb(59, 89, 152)') {
$('#btn-like').css('background-color', '#ffffff').css('color', '#000000');
$('#btn-like').text(data.likeCnt);
} else {
$('#btn-like').css('background-color', '#3b5998').css('color', '#ffffff');
$('#btn-like').text(data.likeCnt);
}
},
failure: function(data){
alert('fail!!')
}
});
});
});
</script>
you'll want to be sure to set the proper mimetype in your HttpResponse
#login_required
def pushLike(request):
...
# return json -- !!not javascript!!
return HttpResponse(simplejson.dumps(...), mimetype="application/json")
--or--
#login_required
def pushLike(request):
...
# return json -- !!not javascript!!
return JsonResponse({"your": "context dictionary"})
If that doesn't work, have you tried parsing the json with your Jquery code?
ie:
$.ajax({
...
success: function(data){
var response = $.parseJSON(data);
...
}
});
javascript might actually receiving bytes back from whatever you are serving your django app with... so instead of getting JSON back, you're actually getting string that looks like JSON. http://api.jquery.com/jquery.parsejson/
This is my request in ajax,
var req=$.ajax({
type: "POST",
url: '/create/travel', // or just url: "/my-url/path/"
data: {
csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
startPlace:nameStart,
startLng:lngStart,
startLat:latStart,
endPlace:nameEnd,
...
}
});
Then, it is my view
def createT(request):
if request.is_ajax():
#print(request.POST['board'])
print(Car.objects.get(number_plate=request.POST['number_plate']))
travel1=Travel.objects.create(
name=request.POST['name_travel'],
startPlace=request.POST['startPlace'],
...
)
return render_to_response('travel/meTravel.html',{},context_instance=RequestContext(request))
But django not go to the template, i dont know how i go to other view or open other page, other template,
Simply when i come to this view, i cannot open other view, single django stay in the same page. =$
Help me! Tanks ,
finally, I make a form and send the normal request, Tanks for all...
class TravelForm(ModelForm):
class Meta:
model = Travel
exclude=("responsible",)
widgets = {
'date': DateTimeWidget (attrs={'id':"date"},use_tz=True,bootstrap_version=3)
}
def __init__(self, user, *args, **kwargs):
super(TravelForm, self).__init__(*args, **kwargs)
self.fields['number_plate'].queryset = Car.objects.filter(proprietor=user)
and my view
def TravelCreate(request):
if request.method == "POST":
form = TravelForm(request.user.id, request.POST)
print("POST HERE-----------------=)")
print(form.is_valid())
if form.is_valid():
obj=form.save(commit=False)
obj.responsible = request.user
obj.save()
return HttpResponseRedirect('/TravelsMe')
else:
form = TravelForm(request.user.id)
return render_to_response('travel/travel_form.html', {'form':form}, context_instance=RequestContext(request))
And some code of ajax,
I am submitting a for using dojo's xhrpost. My app runs on ruby on rails. In the controller I am performing a redirect. I store the redirected URL the response headers. I access the redirected URL on the client and then load the redirected URL on the client. The following is the code.
In the view, performing ajax submit using dojo.xhrpost
function () {
var form = dojo.byId("form_id");
dojo.connect(form, "onsubmit", function(event){
// Stop the submit event since we want to control form submission.
dojo.stopEvent(event);
var xhrArgs = {
form: dojo.byId("form_id"),
handleAs: "text",
load: function(data, ioargs){
//getting redirected url from response header
var new_url = ioargs.xhr.getResponseHeader("new_url");
//redirecting to the url
document.location.href = new_url;
},
error: function(response){
//handling error
}
}
//submitting for to action1 of controller
var deferred = dojo.xhrPost(xhrArgs);
});
}
Code in controller
def action1
new_url = url_for(:controller=>"controller", :action => "action2")
#passing the new URL as parameter in the redirection
redirect_to :action2, :new_url => new_url
end
def action2
#getting the new url from the params and saving it in respone header so that it can be accesses in client
response.headers["new_url"] = params[:new_url]
end
This worked fine on my local host. But when I put it on my server its failing.
I am getting the ioargs.xhr.status as "0". data is " ". Though the form is getting saved response is empty and no response headers are getting set.
Please Help.
I had to modify the controller a bit.
def action1
if request.xhr?
render :json => new_url.to_json
else
#follow normal redirection
redirect_to :action2
end
Also in the ajax call
var xhrArgs = {
form: dojo.byId("form_id"),
handleAs: "json",
load: function(data, ioargs){
//getting redirected url from data
document.location.href = data;
},
error: function(response){
//handling error
}
Basically I found out returning the entire HTML page as response in not the right way.
Only the URL should be returned in the response and redirection should be done from the View,