@never_cache
@login_maybe_required
def tag_autocomplete(request):
    text = request.GET.get("text")
    product_id = request.GET.get("product-id")
    if text is not None:
        tags = model.Tag.objects.filter(name__icontains=text)
        if product_id is not None:
            tags = tags.filter(Q(product=product_id) | Q(product=None))
    else:
        tags = []
    suggestions = []
    for tag in tags:
        # can't just use split due to case; we match "text" insensitively, but
        # want pre and post to be case-accurate
        start = tag.name.lower().index(text.lower())
        pre = tag.name[:start]
        post = tag.name[start + len(text):]
        suggestions.append({
                "preText": pre,
                "typedText": text,
                "postText": post,
                "id": tag.id,
                "product-id": tag.product.id if tag.product else None,
                "name": tag.name,
                "type": "tag",
                })
    return HttpResponse(
        json.dumps(
            {
                "suggestions": suggestions
                }
            ),
        content_type="application/json",
        )
Return autocomplete list of existing tags in JSON format.
dataset/ETHPy150Open mozilla/moztrap/moztrap/view/manage/tags/views.py/tag_autocomplete