I have a view that transforms a queryset into a list which is then returned as JSON for further use of Ajax autocmplete on client-side. However, since I need multiple fields (namely poller_text and poller_id) of each object Ajax requires the following structure:
[
{
"value": "poller_text",
"label": "poller_text",
"url": "poller_id"
},
{
"value": "poller_text",
"label": "poller_text",
"url": "poller_id"
},
]
Right now this is what I get using the view below:
["poller_text", "poller_id", "poller_text", "poller_id"]
# View
def autocomplete(request):
if 'term' in request.GET:
qs = Poller.objects.filter(poller_text__icontains=request.GET.get('term'))
pollers = list()
for poller in qs:
pollers.append(poller.poller_text)
pollers.append(poller.poller_id)
return JsonResponse(pollers, safe=False)
else:
pass
I think the append loop is badly designed, but how to get the required structure?
CodePudding user response:
You should append dictionaries, so with:
qs = Poller.objects.filter(poller_text__icontains=request.GET.get('term'))
pollers = [
{'url': poller.poller_id, 'value': poller.poller_text, 'label': poller.poller_text}
for poller in qs
]
return JsonResponse(pollers, safe=False)
for a UUID object, you can use str(…)
to convert it to a string that contains only the UUID:
qs = Poller.objects.filter(poller_text__icontains=request.GET.get('term'))
pollers = [
{'url': str(poller.poller_id), 'value': poller.poller_text, 'label': poller.poller_text}
for poller in qs
]
return JsonResponse(pollers, safe=False)
You can define a truncate function to limit the length of the poller_text
to 30:
def trun_poller_text(mystr):
if len(mystr) > 30:
return f'{mystr}…'
else:
return mystr
and then use this in the view function:
qs = Poller.objects.filter(poller_text__icontains=request.GET.get('term'))
pollers = [
{'url': str(poller.poller_id), 'value': trunc_poller_Text(poller.poller_text), 'label': trunc_poller_Text(poller.poller_text)}
for poller in qs
]
return JsonResponse(pollers, safe=False)
Note: In 2008, Phil Haack discovered a way to obtain data from the outer JSON array. While most browser have implemented countermeasures, it is still better to use a JSON object as "envelope" of the data. That is why a
JsonResponse
[Django-doc] by default does not allow something else than adict
as outer object. It might thus better to wrap the data in a dictionary and keepsafe=True
onTrue
.