I have an application in Django 2.0 in which I use a template with an ajax function from which I want to receive the result of a filter but it generates the following error:
TypeError: <QuerySet [<Curso: Curso object (1)>, <Curso: Curso object (2)>, <Curso: Curso object (3)>]> is not JSON serializable
Views.py
def activaAjax(request):
curso = Curso.objects.filter(pk = request.GET['id'])
cursos = Curso.objects.all()
try:
curso.update(estado=Case(When(estado=True, then=Value(False)),When(estado=False, then=Value(True))))
mensaje = "Proceso de ACTIVACIÓN/INACTIVACIÓN correcto!!!"
data = {'mensaje': mensaje, 'cursos':cursos}
return HttpResponse(json.dumps(data), content_type="application/json")
except:
return HttpResponse(json.dumps({"mensaje":"Error"}), content_type='application/json', status = 500)
return HttpResponse(json.dumps({"mensaje":"Error"}), content_type='application/json')
Queryset can not be directly dump in json by json.dumps()
either you should write queryset.values_list('field1',flat=True)
or if you want more than 1 field from object you should write queryset.values_list('field1','field2',..)
convet it to list with list(queryset.values_list('field1','field2',..))
and pass it in your data as
data = { 'corsos' : list(queryset.values_list('field1','field2',..)) }
2) Or you can also do
from django.core import serializers
serialized_qs = serializers.serialize('json', queryset)
data = {"queryset" : serialized_qs}
return JsonResponse(data)
Related
I have messages and attachments to them (photos, documents, etc.). When I pass data to the serializer, I find that it is empty.
serializer:
class MessageAttachmentSerializer(serializers.ModelSerializer):
file = serializers.FileField()
class Meta:
model = MessageAttachment
fields = ("file", "message", "size")
view:
#api_view(["POST"])
def stuff_message(request):
data = request.data.copy()
data["sender"] = request.user.id
serializer = MessageSerializer(data=data, context={"request": request})
serializer.is_valid(True)
saved_msg = serializer.save()
if request.FILES:
data["message"] = saved_msg
attachment_serializer = MessageAttachmentSerializer(data=data, context={"request": request}, many=True)
attachment_serializer.is_valid(True)
attachment_serializer.save()
try:
bot.send_message(serializer.validated_data["receiver"].telegram_id, text=serializer.validated_data["text"])
except ApiTelegramException:
return Response("Chat undefined.", status=status.HTTP_404_NOT_FOUND)
return Response()
My message serializer works fine. When trying to output validated_data or data from MessageAttachment I get an empty list. Doesn't throw errors.
Corrected to:
#api_view(["POST"])
def stuff_message(request):
request.data._mutable = True
request.data["sender"] = request.user.id
serializer = MessageSerializer(data=request.data)
serializer.is_valid(True)
saved_msg = serializer.save()
request.data["message"] = saved_msg.id
attachments = []
for attachment in request.FILES.getlist("file"):
record = request.data
record["file"] = attachment
attachment_serializer = MessageAttachmentSerializer(data=record)
attachment_serializer.is_valid(True)
saved_attachment = attachment_serializer.save()
attachments.append(saved_attachment.file)
try:
bot.send_message(serializer.validated_data["receiver"].telegram_id, text=serializer.validated_data["text"])
for attachment in attachments:
bot.send_document(serializer.validated_data["receiver"].telegram_id, attachment.file)
except ApiTelegramException:
return Response("Chat undefined.", status=status.HTTP_404_NOT_FOUND)
return Response()
Just a guess but make sure you are returning the .data attribute on your serialized data as in:
output = MessageAttachmentSerializer(data=data).data
Reference: https://www.django-rest-framework.org/api-guide/serializers/
It was the "many" argument. It looks like cases with one file and several need to be handled differently when creating data through a serializer.
I have created a view, able to retrieve, update and delete perticular object from data base and when ever i am trying the url path('perticularcustomer/<int:var>', perticular_customers, name='perticular_customers') i get :-
The view firstapp.views.perticular_customers didn't return an HttpResponse object. It returned None instead.
views.py:-
#csrf_exempt
def perticular_customers(request, var):
try:
customer = Customers.objects.get(id=var)
except Customers.DoesNotExist:
return HttpResponse(status=404)
if request == 'GET':
serialize = CustomersSerializer(customer)
return JsonResponse(serialize.data, safe=False)
elif request == 'PUT':
data = JSONParser().parse(request)
serialized = CustomersSerializer(customer, data=data)
if serialized.is_valid():
serialized.save()
return JsonResponse(serialized.data)
return JsonResponse(serialized.errors, status=400)
elif request == 'DELETE':
customer.delete()
return HttpResponse(status=204)
You need to use request.method:
if request.method == 'GET':
Here checkout form open but problem is data entered do not save in database. I have used post method in checkout.html and model of form is created in database. But data put by user do not save in database.
views.py
class CheckoutView(View):
def get(self,*args,**kwargs):
form = CheckoutForm()
context = {
'form': form
}
print("get is working")
return render(self.request,"checkout.html",context)
def post(self,*args,**kwargs):
form = CheckoutForm(self.request.POST or None)
print("Now post is also working")
#NOT WORKING
if form.is_valid():
street_address = form.cleaned_data.get('street_address')
apartment_address = form.cleaned_data.get('apartment_address')
country = form.cleaned_data.get('country')
zip = form.cleaned_data.get('zip')
billing_address = BillingAddress(
user = self.request.user,
street_address = street_address,
apartment_address = apartment_address,
country = country,
zip = zip
)
billing_address.save()
return redirect('core:checkout')
messages.warning(self.request,"failed checkout")
return redirect('core:checkout')
I have the below code in a basic Django view, which creates a new product and I am using AJAX to filter a list of industries. I would like to move the ajax processing code into a separate method but I am getting that the view didn't return an HttpResponse object. It returned None instead.
Can anyone recommend the way to separate it out safely? I have other views that use the exact logic.
def new_instrument(request):
if request.is_ajax() and request.method == 'GET':
if request.GET.get('typeis') =='industry':
print('Now loading industries')
sectorid = int(request.GET.get('sector_is'))
sector = models.SecSectorMaster.objects.filter(pk=sectorid).order_by('sectorname')
industries = models.SecIndustryMaster.objects.filter(sectorid=sector).order_by('industryname')
industry_dict = {}
for this_i in industries:
industry_dict[this_i.industryid] = this_i.industryname
return HttpResponse(
json.dumps(industry_dict),
content_type="application/json"
)**
if request.method == 'POST':
mainform= forms.EditInstrumentForm(sector,industrygroup,industries,request.POST,prefix="main")
if mainform.is_valid():
security = mainform.save()
selectid = security.pk
return redirect('instrumentsapp.views.security_list')
else:
return render(request, 'instrumentsapp/edit_instrument.html', {'mainform': mainform})
else:
mainform = forms.EditInstrumentForm(prefix="main")
return render(request, 'instrumentsapp/edit_instrument.html', {'mainform': mainform})
You can separate your view and use JsonResponse directly, and you should return a response if your test fail, this might be your issue since they told you that it returned None instead. I believe you should write something like this
from django.http import JsonResponse
def get_industry(request):
if request.is_ajax() and request.method == 'GET':
if request.GET.get('typeis') =='industry':
print('Now loading industries')
sectorid = int(request.GET.get('sector_is'))
sector = models.SecSectorMaster.objects.filter(pk=sectorid).order_by('sectorname')
industries = models.SecIndustryMaster.objects.filter(sectorid=sector).order_by('industryname')
industry_dict = {}
for this_i in industries:
industry_dict[this_i.industryid] = this_i.industryname
return JsonResponse(industry_dict)
return JsonResponse({'industry': None})
Is there a way I can reference a list containing data from my database (item_list = inventory.objects.order_by('name')) in my jquery AJAX call?
This is my code:
/models.py:
class phonebook(models.Model):
name = models.Charfield(max_length=200)
phone_number = models.CharField(max_length=100)
/views.py:
def phonebook_home(request):
global phonebook
phonebook = phonebook.objects.order_by('name')
def get_next_3_contacts(request):
returnedContacts = phonebook[contactIndex:contactIndex+3]
return HttpResponse(phonebook)
/main.js:
var = ajax_call {
type: 'GET'
url: DEFINED_URL
data: {
index: contactIndex
},
dataType: 'html'
success: function (returned, textStatus_ignored, jqXHR_ignored) {
var contactIndex = 0
function phonebook_list(name, phone_number) {
"<li>" + name + " : " + phone_number + "</li>"
}
for(var index=0; index < 3; index++) {
var name = phonebook[index].name
var phone_number = phonebook[index].phone_number
$("ul").append(phonebook_list(name, phone_number))
}
contactIndex += 3
}
The phonebook[index].name / .phone_number returns "undefined" on my page. I want to keep my js file separate from my template file as it will be easier for me to debug, but unfortunately, this problem has stumped me. I also inputted an alert to test out if any data was being returned from the data base, which only returns a string containing the names of the contacts with no spacing in between contact names. Ex: "JaredSarahJohn".
All help and any bit of advice is appreciated!
A couple of things need to be cleaned up in order for this solution to work:
Your idea that global phonebook will be available from within get_next_3_contacts() is incorrect. When you make the AJAX call that will ultimately invoke get_next_3_contacts() the variable phonebook is no longer available. It went out of scope when the call to phonebook_home() completed.
What's the solution? Change phonebook_home() to accept an offset and count parameters. Have it hit the database and return the requested quantities. This is called pagination and is something you should get familiar with!
def phonebook_home(request, offset, count):
phonebook = phonebook.objects.all()[offset:offset+count]
But how do we get those results down to your AJAX handler? You can't just "return" a list of objects to the HTTPResponse() function - it's looking for text to render, not Model objects.
import json
from django.http import JsonResponse
def phonebook_home(request, offset, count):
status = "OK"
return_data = ""
try:
phonebook = phonebook.objects.all()[offset:offset+count]
return_data = json.dumps(phonebook)
exception:
status = "UH OH"
return JsonResponse({'data': return_data, 'status': status)