Django ajax passing variable to the views - django

I'm new with Django + Ajax. My Problem is I can't get the value from my ajax POST request. I'm using the jquery post.
My task is to sort the draggable list item. The drag and drop is not the problem. Getting the values from POST request is the problem. It returns MultiValueDictKeyError
"Key 'ages' not found in <QueryDict: {u'action': [u'updateRecords'], u'ages[]': [u'80', u'81', u'79', u'82', u'83', u'84', u'85', u'86']}>"
here is my ajax:
$(function() {
var url = ""; /* won't place it*/
$("ul#ages").sortable({ opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable("serialize") + '&action=updateRecords';
$.post(url, order, function(theResponse){
alert('success');
});
}
});
});
here is the views:
if request.is_ajax():
if request.POST['action'] == "updateRecords":
update_record_array = request.POST['ages']
order_counter = 1;
for record_id in update_record_array:
Age.objects.filter(id=record_id).update(order_id=order_counter)
order_counter += 1
Can anyone help me out?
Thanks!

The error message shows what is wrong - you're looking up a key ages, but you're sending something called ages[] with some extra square brackets.
If you've put those brackets in the field name, you don't need them - that's a PHP-ism. (It might not be your fault: jQuery has been known to do add them itself.) In any case, you'll want to use request.POST.getlist(fieldname) to get the list of multiple values associated with that key.

Related

I want to get data from JavaScript with Django

There is price filtering written in JavaScript in the template. I want to take the price range given in this filter with dajngo and write a filtering function. I couldn't because I don't know JavaScript. How will I do?
So, i want to write a django function that takes the given start and end values and sorts the products accordingly.
main.js
// PRICE SLIDER
var slider = document.getElementById('price-slider');
if (slider) {
noUiSlider.create(slider, {
start: [1, 100],
connect: true,
tooltips: [true, true],
format: {
to: function(value) {
return value.toFixed(2) + '₼';
},
from: function(value) {
return value
}
},
range: {
'min': 1,
'max': 100
}
});
}
I'm not familiar with noUiSlider but you would need to get the from and to values into Django - you can do that either by submitting a form when clicking FILTER or by sending an AJAX request. I presume you would just submit the form in a standard page submission as you aren't familiar with JS (and therefore AJAX).
def your_view(request)
filter_from = request.POST.get('slider_from')
filter_to = request.POST.get('slider_to')
YourModel.objects.filter(value__gte=filter_from, value__lte=filter_to)
...
You will need to replace slider_from and slider_to with the key values that are sent by the slider input in request.POST - this will be the name of the inputs themselves. You can wrap request.POST in a print statement to easily see what these are. It's just a matter of getting the values and passing them into the filter() function of your model.

Google Tag Manager: update cookie value and fire tag if value has changed

I have the follow JS variable:
function() {
var products = [];
prods.forEach(function(prod) {
products.push(prod.ACode + '-' + prod.BCode);
});
return products.join('|');
}
The output is an array that contains codes like these:
C1K-DR|A2D-AH|B1T-S1|
These values are being pushed into a cookie. I'm simply struggling because when the value of the push changes, the cookie doesn't get updated.
After that, I would like to fire a tag based only IF this value has changed.
Thanks anyone who can help.

django-autocomplete-light add parameter to query url

I'm trying to pass some data along to the autocomplete_light.AutocompleteModelBase so I can exclude some models from the search. I'm trying to use the Dependencies info in the docs here
but I can seem to get it.
The id of the input is id_alternate_version-autocomplete, so I'm trying:
$("#id_alternate_version-autocomplete").yourlabsWidget().autocomplete.data = {'id': 'foo'};
But the url called looks like http://127.0.0.1:8000/autocomplete/FooAutocomplete/?q=bar
I want: http://127.0.0.1:8000/autocomplete/FooAutocomplete/?q=bar&id=foo
How can I do something like that?
DAL provides a way to do this with "forwarding" of another rendered form field's value.
See http://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#filtering-results-based-on-the-value-of-other-fields-in-the-form
This is how I did it:
$(document).ready(function() {
$('form#recipe').on('change propertychange keyup input paste', function() {
var ingredient_item_type = $("form#recipe input[type='radio']:checked").val();
var widget = $("form#recipe input#id_ingredients_text").parents('.autocomplete-light-widget');
if(ingredient_item_type) {
widget.yourlabsWidget().autocomplete.data['hello'] = 'world';
}
});
});
Javascript acrobatics aside, the key observation is thus:
anything you put in the .data object of the autocomplete widget will
automatically be made part of the GET request. HTH.

Passing a list in a url inside a TokenInput with Django, he only pass the last one

I am using jquery-tokeninput as an autocomplete to retrieve some objects in my app.
My js code to initialize the autocomplete is this:
function initialize_search(model, input_busca) {
var url = reverse('autocomplete.'+model) + "?tipos[]=almoxarifado&tipos[]=estoque";
var data = $(input_busca).data('tokeninput');
$(input_busca).tokenInput(url, {
hintText: 'Start to type',
preventDuplicates: true,
queryParam: 'name',
noResultsText: 'No results',
searchingText: 'Search',
prePopulate: data
});
}
All I want is to receive the parameter 'tipos[]' in my view, like this:
types = request.GET.getlist('tipos[]')
And receive this:
[u'almoxarifado', u'estoque']
But when i do this, he only gives me the last one and not all the list, in this case:
[u'estoque']
This is how I call the autocomplete function inside the js:
inicializa_busca('endereco', $("#id_enderecos"));
You must be aware that, ajax is to pass small data, check the size of this list, maybe is better an full post submission!

Django - jquery : populate combobox based on selection of another combobox

I am quite new to Django and jquery stuff. I am trying to populate a comboBox (ChoiceField in Django) based ont the choice selected in another comboBox (without reloading the page).
I can't find any simple example of such a basic application of ajax.
For now I'm call the following ajax function when I select an item from the first dropdown list.
function get_asset_from_type(){
var type_asset = $("#id_type").val();
var data = {type_asset:type_asset};
var args = {type:"POST", url:"/asset/etatType/", data:data};
$.ajax(args);
alert(type_asset);
return false;
};
It alerts the right type but gives a 403 error on the given url. Weird thing is this url works the first time I load the page. I don't understand what's going on..
EDIT:
403 error seems to be gone, remains the initial question :)
I think you're running up against a CSRF problem. As Django by default blocks POST requests that do not have a CSRF Token with a 403. There are a couple ways to deal with this in JS. One is to pull the value out of the cookie, the code to do that can be found here: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
or you can do it by passing the CSRF_TOKEN in with the javascript script tag:
<script src='myjavascript.js?CSRF_TOKEN={{ csrf_token }}'></script>
Note that it's using a double braket, instead of {%%}. This gets the value of the token, instead of the form input.
function getOptionsFromScriptSrc() {
// Get last script tag in parsed DOM.
// Due to the way html pages are parsed,
// the last one is always the one being loaded.
var options = {}
var js_src = $('script').last().attr('src');
if(js_src.match(/\?/)) {
var options_list = js_src.split('?')[1].split('&');
for(var i = 0; i < options_list.length; i++) {
var tmp = options_list[i].split('=');
options[$.trim(tmp[0])] = $.trim(tmp[1]);
}
}
return options;
}
function get_asset_from_type(){
var options = getOptionsFromScriptSrc();
var type_asset = $("#id_type").val();
var data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
var args = {type:"POST", url:"/asset/etatType/", data:data};
$.ajax(args);
alert(type_asset);
return false;
};
I haven't, of course, tested this code, but I have used this method before and it works pretty well.
To the main problem of populating a select box, you need to specify a callback for your ajax post, and then deal with the data returned from your server:
function get_asset_from_type(){
var options = getOptionsFromScriptSrc();
var type_asset = $("#id_type").val();
var post_data = {type_asset: type_asset, csrfmiddlewaretoken: options['CSRF_TOKEN']};
$.post('/asset/etatType/', post_data, function(data){
// Assuming server is going to respond with the html of the options, eg: <option value="1">One</option><option value="2">Two</option>...
$('#id_ofmyselectbox').append(data);
});
};