Как получить Django queryset в структуре данных Ajax conform?

У меня есть представление, которое преобразует набор запросов в список, который затем возвращается в виде JSON для дальнейшего использования Ajax autocmplete на стороне клиента. Однако, поскольку мне нужно несколько полей (а именно poller_text и poller_id) каждого объекта, Ajax требует следующей структуры:

[
    {
        "value": "poller_text",
        "label": "poller_text",
        "url": "poller_id"
    },
    {
        "value": "poller_text",
        "label": "poller_text",
        "url": "poller_id"
    },
]

Сейчас вот что я получаю, используя вид ниже:

["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

Я думаю, что цикл append плохо продуман, но как получить требуемую структуру?

Вы должны добавить словари, поэтому с:

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)

для объекта UUID, вы можете использовать str(…) для преобразования его в строку, содержащую только 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)

Вы можете определить функцию truncate, чтобы ограничить длину poller_text до 30:

def trun_poller_text(mystr):
    if len(mystr) > 30:
        return f'{mystr}…'
    else:
        return mystr

и затем используйте это в функции просмотра:

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)

Примечание: В 2008 году Фил Хаак обнаружил способ получения данных из внешнего массива JSON. Хотя в большинстве браузеров реализованы контрмеры, все же лучше использовать JSON-объект в качестве "оболочки" данных. Именно поэтому в качестве "оболочки" данных используется объект JsonResponse [Django-doc]. по умолчанию не допускает в качестве внешнего объекта что-то другое, кроме dict. Возможно поэтому лучше обернуть данные в словарь и держать safe=True на True.

Вернуться на верх