Django, passing JSON to frontend, 'str' doesn't have 'iteritems' - javascript

I'm creating json data this way:
def get_all_from_database():
urls = Url.objects.all()
ips = Ip.objects.all()
urls_json = serializers.serialize('json', urls)
ips_json = serializers.serialize('json', ips)
return urls_json, ips_json
and I try to pass it to frontend using ajax:
#csrf_exempt
def send_results(request):
if request.is_ajax():
address = request.POST.get('url')
urls, ips = get_all_from_database()
return HttpResponse(urls, ips)
js code:
$.ajax({
type: "POST",
url: "/link_finder/send_results/",
data: {
url : web_page,
},
success: function(data) {
alert(data);
},
error: function(xhr, textStatus, errorThrown) {
alert("Please report this error: "+errorThrown+xhr.status+xhr.responseText);
}
And I get this error:
INTERNAL SERVER ERROR500AttributeError at /link_finder/send_results/
'str' object has no attribute 'iteritems'
Why? And what should I change?

HttpResponse takes only one body argument, you are passing in two.
Don't create two JSON strings, build one, using a custom serializer to handle multiple querysets:
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.core import serializers
from django.db.models.query import QuerySet
def get_all_from_database():
urls = Url.objects.all()
ips = Ip.objects.all()
return urls, ips
class HandleQuerySets(DjangoJSONEncoder):
""" JSONEncoder extension: handle querysets """
def default(self, obj):
if isinstance(obj, QuerySet):
return serializers.serialize("python", obj, ensure_ascii=False)
return super(HandleQuerySets, self).default(obj)
#csrf_exempt
def send_results(request):
if request.is_ajax():
address = request.POST.get('url')
urls, ips = get_all_from_database()
data = HandleQuerySets().encode({'urls': urls, 'ips': ips})
return HttpResponse(data, content_type='application/json')
I've also set the correct Content-Type header for you.

Related

Access a json object form views django

i have tried a number of suggestions but need help.
in my views.py
def findnamesurname(request):
username = request.POST['username']
obj = Users.objects.all().values("first_name").filter(username=username)
return HttpResponse(obj)
in my js
$.ajax({
url: "/findnamesurname",
method: "POST",
data: {
'csrfmiddlewaretoken': '{{csrf_token}}',
"username": data,
},
success: function (data) {
alert(JSON.stringify(data))
}
})
}
I want to get first name please in a variable
How to access this object please.
Whet I alert I get:
{'first_name': 'hello', 'last_name': 'there'}
Not sure I got your question right. But if you want to retrieve the first and last name of a user by its username, you first need to filter/search that user in the database. Then you can send the response by using JsonResponse.
from django.http import JsonResponse
from django.http import Http404
def findnamesurname(request):
username = request.POST["username"]
try:
user = YourUserModel.objects.get(username=username).values(
"first_name", "last_name"
)
except YourUserModel.DoesNotExists:
raise Http404
return JsonResponse(user)

Not able to retrieve data values from Ajax GET call into Django view

I am trying to query the employee list based on parameter I send
through ajax call inside data, but it giving me an error (i want it
through GET req only )
Js ajax func
$(document).ready(function () {
$(".call_ajax").click(function () {
$.ajax({
url: "/employee_list",
type: "GET",
contentType: "application/json",
dataType: "json",
data: {
designation: "soft eng",
},
headers: {
"X-CSRFToken": csrftoken,
Authorization: my_token,
},
success: function (data) {
console.log(data);
},
error: function (xhr) {
//Do Something to handle error
console.log(xhr.error);
},
});
});
my view
#csrf_exempt
#api_view(['GET', 'POST', 'PUT', 'DELETE'])
#permission_classes([IsAuthenticated])
#authentication_classes([TokenAuthentication])
def employee_list(request):
if request.method == 'GET':
data_ = request.data['designation']
print(data_)
employees = Employee.objects.all()
students = Student.objects.all()
user = MyUser.objects.all()
serializer = EmployeeSerializer(employees, many=True)
serialized_sudents = StudentSerializer(students, many=True)
multi = {
'employees': serializer.data,
'students': serialized_sudents.data
}
# serializer2 = UserSerializer(user, many=True)
return JsonResponse(multi, safe=False)
error i am getting in browser
GET http://127.0.0.1:8000/employee_list/ 500 (Internal Server Error)
error in Django log
File "C:\Users\atif\PycharmProjects\CodePlatform\syntax_fight\api_\views.py", line 42, in employee_list
data_ = request.data['designation']
KeyError: 'designation'
request.data returns the parsed content of the request body.
This is similar to the standard request.POST and request.FILES
You can use request.GET.get('designation')
#csrf_exempt
#api_view(['GET', 'POST', 'PUT', 'DELETE'])
#permission_classes([IsAuthenticated])
#authentication_classes([TokenAuthentication])
def employee_list(request):
if request.method == 'GET':
data_ = request.GET.get('designation') # Here I made changes
print(data_)
employees = Employee.objects.filter(designation=data_) # Map parsed data with database field
students = Student.objects.all()
user = MyUser.objects.all()
serializer = EmployeeSerializer(employees, many=True)
serialized_sudents = StudentSerializer(students, many=True)
multi = {
'employees': serializer.data,
'students': serialized_sudents.data
}
# serializer2 = UserSerializer(user, many=True)
return JsonResponse(multi, safe=False)
or
You can override get_queryset method. As for query string parameters request.data holds POST data, you can get query string params through request.query_params
def get_queryset(self):
data = self.request.query_params.get('designation')
queryset = Model.objects.filter() # use whatever you want filter
return queryset
To know more about request.data and request.query_params, here is the link
Request parsing link
It is most probably because you are using GET, but the data resides in body. Have a look at this. To try to fix this, change your request method to POST:
$.ajax({
url: "/employee_list",
type: "POST",
...

How can I access a Django returned json object in javascript / on the client-side?

I'm having hard times to find a way to use my Django returned data on the clientside. I think I mix up several concepts here.
This is my view that calls the model StocksPrice and returns all data in the table column stockName:
def getStocksAvailable(request, *args, **kwargs):
StocksAvailable = serializers.serialize('json', StocksPrice.objects.values(stockName))
return HttpResponse({"data": StocksAvailable})
and according Javascript part for testing purposes:
var received_data = "{{ StocksAvailable }}"
console.log(received_data);
# Outputs: {{ StocksAvailable }}
I also tried it using render in the view:
def getStocksAvailable(request, *args, **kwargs):
StocksAvailable = serializers.serialize('json', StocksPrice.objects.values(stockName))
return render({"data": StocksAvailable})
Why does JS logs it as a string whereas it is supposed to be a variable containing the returned json object? And how could I basically print the returned data from the view for debugging (maybe s.th. is wrong with the json itself)?
Updated Version #Willems response
Url mapping:
urlpatterns = [
path('terminal/getStocksAvailable/', get_stocks_available),
]
View
def get_stocks_available(request, *args, **kwargs):
stocks_available = serializers.serialize('json', StocksPrice.objects.values(stockName))
return JsonResponse({'data': json.loads(stocks_available)})
Model
class StocksPrice(models.Model):
stockName = models.CharField(max_length=100, blank=False)
[...]
class Meta:
db_table = 'StocksPrice'
JS
$( document ).ready(function() {
$.ajax('getStocksAvailable/', {
method: 'GET',
async: "True",
dataType: "json",
success: function () {
var received_data = "{{stocks_available}}"
console.log(received_data);
}
})
});
which now throws:
Traceback (most recent call last):
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Jonas\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Jonas\Desktop\CFD\CFD\terminal\views.py", line 10, in get_stocks_available
stocks_available = serializers.serialize('json', StocksPrice.objects.values(stockName))
NameError: name 'stockName' is not defined
[17/May/2020 14:36:56] "GET /terminal/getStocksAvailable/ HTTP/1.1" 500 16181
[17/May/2020 14:36:56] "GET /terminal/getStocksAvailable/ HTTP/1.1" 500 16181
Why does JS logs it as a string whereas it is supposed to be a variable containing the returned json object?
Because serializers.serialize(..) returns a string. If you want to wrap it in an object, you can for example decode it:
import json
from django.http import JsonResponse
def get_stocks_available(request, *args, **kwargs):
stocks_available = serializers.serialize('json', StocksPrice.objects.values(stockName))
return JsonResponse({'data': json.loads(stocks_available)})
EDIT1:
You furthermore need to pass a value for stockName, and process the result.view_data (this is a parameter in the data):
$( document ).ready(function() {
$.ajax('getStocksAvailable/?stockName=???', {
method: 'GET',
async: "True",
dataType: "json",
success: function (result) {
var received_data = result.view_data;
console.log(received_data);
}
})
});
with ??? to fill in.
in the view, you can then access request.GET to obtain the value for stockName:
import json
from django.http import JsonResponse
def get_stocks_available(request, *args, **kwargs):
stockName = request.GET['stockName']
stocks_available = serializers.serialize('json', StocksPrice.objects.values(stockName))
return JsonResponse({'data': json.loads(stocks_available)})
EDIT2:
If you want to use values from a column named stockName, then you should use:
import json
from django.http import JsonResponse
def get_stocks_available(request, *args, **kwars):
stocks_available = serializers.serialize('json', StocksPrice.objects.values('stockName'))
return JsonResponse({'data': json.loads(stocks_available)})
and at the JavaScript side:
$( document ).ready(function() {
$.ajax('getStocksAvailable/', {
method: 'GET',
async: "True",
dataType: "json",
success: function (result) {
var received_data = result.view_data;
console.log(received_data);
}
})
});

How to make POST requests to class-based Views in Django

I have created different class-based views on Django. On the HTML i created some forms make a request with AJAX. My problem is that it gives me
Method Not Allowed (POST)
I don know if i'm doing it rigth, or if i need to modify something for it to work.
My view.py is something like this
class Landing(View):
def get(self,request):
if request.method == 'POST':
if request.is_ajax():
data = {"lat":20.586, "lon":-89.530}
print request.POST.get('value')
return JsonResponse(data)
return render(request,'landing.html',{'foo':'bar'})
And i send the reques from Javascript
$(document).ready(function() {
$('#productos').on('change', function(e) {
//Call the POST
e.preventDefault();
var csrftoken = getCookie('csrftoken');
var value = $('#productos').val();
$.ajax({
url: window.location.href,
type: "POST",
data: {
csrfmiddlewaretoken : csrftoken,
value : value
},
success : function(json) {
console.log(json);
drop(json);
},
error : function(xhr,errmsg,err){
console.log(xhr.status+": "+xhr.responseText)
}
});
});
});
I got some of the code from a web, but i really don't know how to use it, since they used it without class-based views.
So, What does need my code to accept the POST method?
The dispatch method of a class based view determines which function is called, so far you've written a get function, but no post function so just move the logic into a post function.
class Landing(View):
def post(self,request):
if request.is_ajax():
data = {"lat":20.586, "lon":-89.530}
print request.POST.get('value')
return JsonResponse(data)
def get(self, request):
return render(request,'landing.html',{'foo':'bar'})

How to access Backbone Fetch data server side

I have a backbone model that I am calling fetch with. I have a flask server on which i need to access the id of the backbone model. I cannot seem to get my hands on the id of the model on the server. How can I access the entityId in my flask code
BB.Politician = Backbone.Model.extend({
defaults: {
type: "Politician"
},
url: "/my_url_here"
});
var currentUser = new BB.Politician({"entityId": "1625"});
currentUser.fetch({
//method: "POST",
success: function(user){
currentUserView.render();
}
});
#Flask server code
#app.route('/my_url_here', methods=['GET', 'POST'])
def return_poitician():
print request
print request.args
print request.values
#none of the above print statements are giving me the "entityId"
return data
I also tried adding in the id in the route but that just threw a 404 error when the fetch() executed:
#app.route('/my_url_here/<entityId>', methods=['GET', 'POST'])
def return_poitician(entityId):
print entityId
#app.route('/my_url_here/<entityId>', methods=['GET', 'POST'])
isn't picking up any id because you aren't sending any.
Backbone fetch uses the id field of the model to construct the fetch URL, in your case I would recommend turning the entityId into id:
BB.Politician = Backbone.Model.extend({
defaults: {
type: "Politician"
},
url: "/my_url_here"
});
var currentUser = new BB.Politician({"id": "1625"});
and let Backbone construct the GET, which would look like:
"/my_url_here/" + this.get('id'); // this refers to model
which turns into
"/my_url_here/1625"
Backbone.Model.url also accepts function as value so you can define your own logic for constructing URLs. For instance, if you must retain the entityId you can construct your url like:
url: function () {
return "/my_url_here" + this.get('entityId');
}

Categories

Resources