How to convert QueryDict to python dictionary - django

I am trying to post some data from Dojo to Django application. I use postData to post the data to the server
here is the code snippet
var csrftokenval = dojo.cookie('csrftoken');
var selectedmoid1 = tree.getSelectedItemId();
var loadURL = '/calerts/';
dojo.rawXhrPost({
url : loadURL,
headers : {'X-CSRFToken':csrftokenval},
postData: dojo.toJson({'selectedmoid':selectedmoid1,'previousval':previousVal}),
handleAs: "text",
load : function(data, ioArgs){
dojo.byId('content-main').innerHTML = data;
},
error : function(data, ioArgs){
}
});
In the Django views i get the data as
def calerts(request):
user = request.user
compId = int(request.session.get('USERCOMPANY_ID','-1'))
listCount = 25
print '0000000000000000000000000000000 ',request.POST
print 'post dictionary ::: ',request.POST.dict()
I know to get the dict value from querydict using dict() method however in my case the print is
post dictionary ::: {u'{"selectedmoid":"4","previousval":"4"}': u''}
i dont undersand where that final u'' comes from. Also i would like to retrieve the values of selectedmoid and previousval

Your sending the data as a raw JSON post, not a form-encoded one. So you should access request.body, not request.POST, and decode the JSON from there.

Related

Why postman POST method do not provide params in `json` format?

In my flask project, there is a route:
def request_parse(req_data):
if req_data.method == 'POST':
data = req_data.json
elif req_data.method == 'GET':
data = req_data.args
return data
#app.route('/api/d/u', methods=['POST'])
def update(): # name, domain_list, pem_key, pem_cert, origin_ips
data = request_parse(request)
name = data.get('name')
domain_list = data.get('domain_list')
pem_key = data.get('pem_key')
pem_cert = data.get('pem_cert')
origin_ips = data.get('origin_ips')
in Postman I request it like this:
I use postman request the api:
you see it is POST method, and in my project debug, I found the request data is in form,not in json.
I also tried form-data and x-www-form-urlencoded format, all are in form.
why postman POST method do not provide params to request.json? and is it possible to provide params in request.json?
If you want to send it as JSON, change from x-www-form-urlencoded to raw and you should see a drop down for Text, JSON, HTML. You can then select JSON

How to properly return Json reponse to template for ajax/jquery?

Here I am trying to search with the help of ajax and jquery with my django view. When I try to search like this by returning the JsonReponse instead of html_template it doesn't return data below the corresponding id in html
But When I return html from django view and create the new html for this searching results and including this template in the original template works perfectly but I find this a longer process So I tried to return json reponse from view and use that json objects in the template like this but it is not working.
How can I solve this ? I think I need to work on the ajax part .
def search_users(request):
q = request.GET.get('q')
if q:
users = get_user_model().objects.filter(is_active=True).filter(profile__full_name__icontains=q)
data = {'users': users}
else:
users = get_user_model().objects.filter(is_active=True)
data = {'users':users}
return JsonResponse(data)
ajax
$(function() {
$('#search_users').keyup(function() {
$.ajax({
type: "GET",
url: "{% url 'dashboard:search_users' %}",
data: {
'q' : $('#search_users').val(),
},
success: searchSuccess,
dataType: 'json'
});
});
});
function searchSuccess(data, textStatus, jqXHR)
{
$('#search_users_results').json(data) #doing html instead of json works after returning html from django view
}
In the terminal
TypeError: Object of type QuerySet is not JSON serializable
[15/Mar/2020 14:02:53] "GET /admin/dashboard/search/users/?q=tyj HTTP/1.1" 500 22660
You have to extract values out of the query before sending it across instead of sending the model instance as it can't be serialized, is what the exception is saying.
So, you can just append .values() in the end and put in the list as below -
data = {'users': list(users.values())}
You may refer to it here.

Unable to get POST or GET form data while using AJAX

Have been trying to filter data using django-filters. The code is working when I send a separate POST or GET request from the template. I want to avoid that extra reload that's taking place to filter the table of information.
Here's the view:
def search(request):
dynamic_filter = [f.name for f in Controlpanel._meta.get_fields()]
class UserFilter(django_filters.FilterSet):
class Meta:
model = Controlpanel
fields = dynamic_filter
user_list = Controlpanel.objects.all()
user_filter = UserFilter(request.GET.get("filters[]"),
queryset=user_list)
chart = list(user_filter.qs.values())
return JsonResponse(chart, safe=False)
Here's the AJAX code that calls this above view:
$('#filter-data').on('submit', function (event) {
event.preventDefault();
var dynamic = $('#filter-data').serialize();
console.log($('#filter-data').serializeArray())
$.ajax({
url: '/search/',
type: 'GET',
data: {
filters : dynamic
},
dataType: 'json',
success : function(json) {
console.log(json); // log the returned json to the console
console.log("success"); // another sanity check
},
// handle a non-successful response
error : function(xhr,errmsg,err) {
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
The request.GET(or POST) currently stays empty even if I add a CSRF token and make it a POST request.
I came across some question on SO stating that use of request.body solves the issue but even that was a fail.
The issue was that the POST request was being passed as a string.
This solved the issue:
user_filters = request.POST.get('filters', '')
user_filters = user_filters.split("&")
user_filters = {item.split("=")[0]: item.split("=")[1].replace("%20", " ")
for item in user_filters}
user_filters.pop('csrfmiddlewaretoken')

How to read JSON data return by the Facebook access_token

I'm trying to get the facebook username of a logged in user in my site. I have this code in my view (on Django) :
code = request.GET.get('code')
url = 'https://graph.facebook.com/oauth/access_token?client_id=%(id)s&redirect_uri=http://127.0.0.1:8000/skempi/home&client_secret=%(secret)s&code=%(code)s'%{'id':fb_id,'secret':fb_s,'code':code}
response = urllib2.urlopen(url)
html = response.read()
dic = dict(urlparse.parse_qsl(html))
graph_url = 'https://graph.facebook.com/me?access_token='+dic.get('access_token')
when I do return HttpResponseRedirect(graph_url) I can see the JSON data. However, I'm not able to read that data using
import simplejson
d = simplejson.load(graph_url)
context ={'user':d}
return render_to_response('home.html', context, context_instance=RequestContext(request))
I get this error :
'str' object has no attribute 'read'
You have to actually download the JSON before simplejson can decode it.
response = urllib2.urlopen(graph_url)
data = simplejson.load(response)

Is it possible to return an HttpResponse in django with text & a json object?

In my view function, I'd like to return a json object (data1) and some text/html (form). Is this possible?
Here is part of my views.py:
if request.is_ajax() and request.method == 'POST':
...
if form.is_valid():
answer = form.cleaned_data['answer'] # Answer extracted from form is also a string
a1 = ques1.correct_answer
if a1 == answer:
test1 = question_list.get(id=nextid)
form = AnswerForm(test1)
ques1 = question_list.filter(id=nextid) # Filter next question as <qs>
data1 = serializers.serialize("json",ques1) # Json-ize
# ********EDITED HERE **********
variables1 = Context({
'form' : form,
'q1' : data1,
})
#response = HttpResponse()
#response['data1'] = response.write(data1)
#response['form'] = response.write(form)
if nextid <= qsnlen:
return HttpResponse(variables1, mimetype="application/json")
#return HttpResponse(response)
else:
...
I'd like to send back both the form html and the ques1 json object. How can I do this? Thanks in advance.
Just put both pieces of data in a JSON container, one key with the form data and one with the HTML as a rendered string. In the browser, you can just pull both keys out & do your thing.
In your view:
form_json_data = get_form_json_data()
rendered_html = get_the_html()
return HttpResponse(json.dumps({
"formdata": form_json,
"html": rendered_html}),
content_type="application/json")
In js:
$.post(foo, postdata, function(data){
var formdata = data.formdata
var html = data.html;
$(".html-target").replaceWith(html);
do_whatever(formdata);
})
Use JsonResponse
from django.http import JsonResponse
response_data = {put your data into a dict}
return JsonResponse(response_data, status=201)
To do this with one response; you need to send the JSON as a plain text in the context of your template response (HTML).
If you need to send JSON as as a separate JSON object, with its own mime type, then you need to write two views; one that sends back the JSON as application/json and the other that sends back the form (HTML).
EDIT:
You are not returning JSON objects, but you are turning a dictionary that has two items of two different types. As I explained in the comments, in one request/response cycle; you can only return one response which has a specific mime type that is based on the content and how you want the browser to handle it. Most of the time the content type is 'text/html'.
In your scenario, if you want to return both the HTML (which is your form), and the JSON response (which is a string), you need to return HTML.
If you want to return JSON to Jquery as a JSON object; you need to detect the request type. In your front end (the templates), you will initiate two requests - one from the browser, which will return back the form. The other from jQuery, which will return the appropriate JSON object.
Here is a possible approach to this:
def foo(request):
if request.is_ajax():
ctx = dict()
ctx['hello'] = 'world'
return HttpResponse(json.dumps(ctx),content_type='application/json')
else:
return HttpResponse('hello world')