Home > Net >  How to get Django queryset in Ajax conform data structure?
How to get Django queryset in Ajax conform data structure?

Time:09-25

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 a dict as outer object. It might thus better to wrap the data in a dictionary and keep safe=True on True.

  • Related