how to pass objects with django and ajax? - ajax

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

Why is my attacchment serializer not saving data?

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.

why getting The view firstapp.views.perticular_customers didn't return an HttpResponse object. It returned None instead in DRF?

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':

post method of class based view is not working.while get method is responding.form is launched using get method but post is not

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')

Error when returning a HttpResponse from a Django Helper Function

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})

Django AJAX call: Referencing Table in JS

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)

Resources