I am new with Django and AJAX (javascript).
Finally I can send some arguments to a django view. This view render an edit form.
I send the parameters and the view response the form with the info that I need, but I can't to redirect to the form rendered from the view.
AJAX Fucntion:
$.ajax({
type:"GET",
url: "/recepcion/",
datatype: 'json',
data: ({i: idpro[0].innerHTML, a: ano[1].innerHTML, m: mes1[2].innerHTML }),
success: function(data){
window.location.href = data.redirect;
//window.open("GET",url,true)
}
});
django view:
def RecepcionView(request):
idp = request.GET.get('i')
anio = request.GET.get('a')
mes = request.GET.get('m')
if request.method == 'POST':
r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
form = RecepcionForm(request.POST, instance=r)
if form.is_valid():
form.save()
return HttpResponseRedirect('/monitor/')
else:
r = DetalleRecepcion.objects.get(id_proveedor=idp,anio=anio,mes=mes)
form = RecepcionForm(instance=r)
return render_to_response('recepcion.html',
{'form':form},
context_instance=RequestContext(request))
In the firebug consoles I can see the response and is the form with the info that I need.
I don't know how to redirect to the page from the response, I am not sure if I have to add some redirect function in the django view or only in the ajax success function.
I am really new with this two language and I am confused where is the error.
Thanks in advance
I guess from your code that you have a "regular" view (not a view whose purpose is to handle ajax data). Redirecting can be achieved in the view, you do not need ajax.
Just submit the form. In your recepcion.html file write something like
some html
<form method="POST" action=""> <!-- we leave the action part blank, to send the data to the same view -->
{{ form }} <!-- the form you are passing to the template -->
{% csrf_token %} <!-- do not forget the token or django will return an error -->
<input type="submit" name="submit" value="Submit"/>
</form>
some html
Btw:
you can use render (https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render) instead of render_to_response (you will not have to pass the request every time).
you can use the reverse function to redirect to a url. Ie instead of HttpResponseRedirect('/monitor/'), write HttpResponseRedirect(reverse('name_of_the_view_you_want_to_redirect_to')), https://docs.djangoproject.com/en/1.6/ref/urlresolvers/#reverse.
Related
I'm building a web app where user can create markers on a leaflet map. Marker's details are saved in a backend with Django.
My goal is to redirect the user to a detail page to fill marker's detail after clicking on the map.
Here the js code to redirect to url create with an Ajax post.It's run when user click on the leaflet map.
map.on("click", function (e) {
window.location.href = {% url 'create' %};
$.ajax({
url: {% url 'create' %},
data: { markers: markers_dict},
type: "POST"
}).done(function (response) {
console.log(response);
});
}
but I'm struggling in the views.py because this redirect and AJAX post create two request one GET and another POST:
def create_marker(request):
if request.method == "POST":
r = request.POST.get("markers")
print(r)
return JsonResponse({"response":"succeed"})
else:
return JsonResponse({"response":"failed"})
and the urls.py :
url_patterns = [
path("create/",views.create_marker,name="create"),
]
It always returns the failed response even if it prints r in the console. How can I send these frontend data to the create url while redirect to this url and create a django from with these data ?
You are exiting the current page before making the ajax call. Move the redirection into ajax call’s done block. Something like this:
map.on("click", function (e) {
$.ajax({
url: {% url 'create' %},
data: { markers: markers_dict},
type: "POST"
}).done(function (response) {
window.location.href = “{% url 'create' %}/” + response.id;
});
}
You will need one more url in your urls.py for editing the marker object in backend. Try the CBV DetailView.
So first you post to this view with your map data. Once successful, redirect the user to the edit view of the created data.
User clicks on map You create the minimal object in backend
You get the ID of the created object on success
Redirect the user to the form/edit view of that object
User fills out the remaining items
User clicks on save
I want to render html page after ajax success. but i am not getting the proper path for the file. I am using django backend. I am not using django inbuilt function to authenticate. this is my python code.
this is the error
this is my project structure
//this is my javascript code
function admin_login(){
username = document.getElementById("username").value;
password = document.getElementById("password").value;
console.log(username+password);
data={
"username":username,
"password":password
}
$.ajax({
type: 'POST',
url: "http://127.0.0.1:8000/admin_login/",
data:JSON.stringify(data),
success: function(data) {
console.log('sucessfully loggedin')
window.location.href = "/chat/templates/user.html";
}
});
}
You're trying to redirect to a template. Django doesn't work like that.
With or without a redirect, a request from the browser always needs to go to a URL that is handled by a view. Your redirect should be to an actual URL listed in your urls.py.
Alternatively, given that this is a completely standard form that has no need for Ajax, you could remove the script completely. Just let the form submit in the normal way and redirect as the Django code determines.
When the submit button is clicked it goes into the GetProducts action method of my controller which returns a list of dates in JSON that I will be handling in the success function.
However, I keep getting redirected to Products/GetProducts and see the JSON list of dates in the web browser on an empty page. This is normal if ajax is not being used, but I thought I specified that I want this form to be AJAX in the form attributes..
My ultimate goal is to retrieve the dates and then add them to a div on the page without any page redirects or flicker.
form declaration:
<form asp-action="GetProducts" id="myForm" data-ajax="true" data-ajax-method="POST" data-ajax-success="myForm_AjaxSuccess">
<input type="submit" value="Generate Products" class="btn btn-default" />
</form>
the success js function:
function myForm_AjaxSuccess(data) {
alert(data);
}
action method:
// POST: Products/GetProducts
[HttpPost]
//[ValidateAntiForgeryToken]
public IActionResult GetProducts(ProductViewModel vm)
{
IList<DateTime> dateList = new List<DateTime>()
{
new DateTime(2012, 01, 12),
new DateTime(2012, 02, 12,
new DateTime(20162, 03, 12)
};
return Json(dateList);
}
Note that this form is being opened up inside of a Telerik Kendo Dialog Window if it makes any difference. I am not sure why that would prevent the ajax from working when the form is submitted.
Here is my alternate way of doing it for now which is working perfectly, but I want to get it working using the html5 ajax helpers as described above:
$('#myForm').submit(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "/Products/GetProducts",
data: $('#myForm').serialize(),
datatype: "json",
success: function (data) {
alert(data);
}
});
});
#BlakeRivelll: Nothing is preventing AJAX from working (as you mentioned in your question) as the application does go into the "GetProducts" method inside the Controller.
Could you specify the "dataType" in the AJAX call as "json"? You are expecting a JSON return type and not html, yes?
"dataType" is what you're expecting back from the server: json, html, text, etc. jQuery will use this to figure out how to populate the success function's parameter.
This may sound simple, but how do I send the data from a Javascript array in my index.html template to my views.py?
When the user clicks a "Recommend" button, my code calls a function that accesses my database and prints a name on the template.
def index(request):
if(request.GET.get('Recommend')):
sql_handler.recFunc()
context['name'] = sql_handler.name
return render(request, 'polls/index.html', context)
I have an array of checkbox values in Javascript that are calculated after the user presses "Recommend". I want to send it to my index view and use it as the parameter for another function.
So:
def index(request):
if(request.GET.get('Recommend')):
sql_handler.recommend()
context['name'] = sql_handler.name
//something??
tags = check_array_javascript
context['tags'] = tags
return render(request, 'polls/index.html', context)
How can I do this? I've been searching similar questions, but I'm new to Django and web development in general, so I either did not understand the answers or they didn't help me.
Alright, so for sending data from the client (JavaScript) to the backend (your Django app) you need to employ something called Ajax, it stands for Asynchronous JavaScript and XML.
Basically what it does is allowing you to communicate with your backend services without the need of having to reload the page, which, you would have to do using a normal POST or PUT form submission.
The easiest implementation is using jQuery. jQuery is first and foremost a DOM manipulation library but since its inception has grown to encompass much more than that.
A jQuery ajax call looks like this.
$(document).ready(function() {
$.ajax({
method: 'POST',
url: '/path/to/your/view/',
data: {'yourJavaScriptArrayKey': yourJavaScriptArray},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked!");
},
error: function (data) {
alert("it didnt work");
}
});
});
This can then be checked for in your views.py
def index(request):
if request.is_ajax():
#do something
request_data = request.POST
return HttpResponse("OK")
I'm a newbie to both Ajax and Django. To simplify the question assume I have one hidden form and two objects, and I ask the users to click some of the position of the objects. Each clicks fills out a part of the form. I want the form to be filled out once for each object. so twice overall. When the form is filled for the first subject I want to send the form via Ajax to the server, without refreshing the page, and allow the form to be refilled for the second object. However, for some reason I can't get the form to be send via ajax.
here is my code:
index.html:
<html>
<body>
<script src="{{ STATIC_URL }}prototype.js"></script>
<script src="{{ STATIC_URL }}jquery.js"></script>
<script>
objectID= 1;
num_obj = {{num_obj}}
function ajax_post(){
$('#inputform').submit(function() {
$.ajax({
type: 'POST',
url: '/index/',
data: $(this).serialize(),
success: function(data){alert(data)}
}); // end new Ajax.Request
});
}
function onDocumentMouseDown( event ) {
....do stuff
if (objectID < num_obj){
ajax_post()
}
if (objectID == num_obj){
$("form").submit();}
objectID ++;
$("form").clearForm();
document.forms[0].ObjectID.value = objectID;
}
</script>
<form action="" method="post" id="inputform">
<div id="ajaxwrapper">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
</div>
</form>
</body>
</html>
my view.py:
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import *
from firstapp.forms import PracForm3
num_obj=2
def index(request):
Obj.objects.all().delete()
if request.method == 'POST':
form = PracForm3(request.POST)
print "\n\n\n\n\n"
if request.is_ajax():
print "yaaaaay AJAX"
print request.POST
else:
print "noooooo"
print "\n\n\n\n\n"
if form.is_valid():
cd = form.cleaned_data
.....
if cd['ObjectID'] == num_obj:
return HttpResponseRedirect('/submit')
else:
form = PracForm3()
dic = {'form': form, 'num_obj': num_obj, ...}
return render_to_response('index.html', dic, context_instance=RequestContext(request))
my urls.py:
from django.conf.urls import patterns, include, url
from firstapp.views import index, submit
from django.conf import settings
urlpatterns = patterns('',
('^index$', index),
('^submit$', submit),
)
for some reason, my Ajax does not work anyone knows what I'm doing wrong?
This is probably related CSRF for AJAX posts, you have to remember to pass the CSRF token in as POST data with every POST request. You may need to add this code here, which are the Django docs that talk about Django+CSRF+AJAX.
I notice in your Django view that you are redirecting to "submit" Typically with ajax I would not redirect to a different url, I would use a HttpResponse and return some string value, such as JSON. I also don't know why you have print statements in your view, unless you are steeping into that view in a debugger. For testing/debugging you should have a variable that you assign some string to, and then pass that back to your ajax. Then in your ajax you can read the message from the view, something like this.
def index(request):
...
if request.is_ajax():
msg = 'it worked'
else:
msg = 'i am sad'
return HttpResponse(msg)
...
Also you javascript should have a success and error function in the ajax call, you only
have success so you are not catching errors, given the view tad bit your javascript would look like this:
...
success: function(data){alert(data)},
error: function(data){alert(data)}
...
It looks like you may have several issues going on. If you have not done the CSRF stuff that I gave you the link to that is an issue too, for testing use the csrf_exempt if you don't want to address doing it the preferred way. Try the code bits above and see if that makes progress for you.
The csrf token is included in $('#input-form') post request, so I don't think that was the issue. I think the problem is that you aren't converting the context into json in your view. This is from the docs example:
import json
from django.http import HttpResponse
class JSONResponseMixin(object):
"""
A mixin that can be used to render a JSON response.
"""
response_class = HttpResponse
def render_to_response(self, context, **response_kwargs):
"""
Returns a JSON response, transforming 'context' to make the payload.
"""
response_kwargs['content_type'] = 'application/json'
return self.response_class(
self.convert_context_to_json(context),
**response_kwargs
)
def convert_context_to_json(self, context):
"Convert the context dictionary into a JSON object"
# Note: This is *EXTREMELY* naive; in reality, you'll need
# to do much more complex handling to ensure that arbitrary
# objects -- such as Django model instances or querysets
# -- can be serialized as JSON.
return json.dumps(context)
You're requesting /index/ in your ajax call, but your pattern matches /index.
It may caused by the csrf, add #csrf_exempt before the method name will be helpful.
#csrf_exempt
def method(args):
pass
I commented out the CSRF so it wasn't that my ajax function was the problem. Here is the correct way:
function ajax_post(){
$.ajax({
type: 'POST',
url: '/index/',
data: $(this).serialize(),
success: function(data){alert(data)}
}); // end new Ajax.Request
}
thanks for all your input