My Profile Photo

Tamay Eser Uysal


Road Cycling Fan, Passsionate About Coding,Coffee Lover


Very Basic Search Component With Django

I didn’t write Django for a long time but I took an offer from a good company at the same time my closest friends write their thesis because of those reasons I looked to Django again.

My friends need to make a search bar for a really small set of data. First I made a new page for search and in this page there is a search bar. You write your word and you need to click to search button. Yes, that was an easy way but after that I back to my home and I thought that If I can make an endpoint and Ajax call to that endpoint this can be much better user experience and can be used for template.

That was the first version of the code:

# ~/views.py

from django.http import JsonResponse

def ajax_search(request):
    if(request.method == "POST"):
        lectureQueryset = ""
        word = request.POST["word"]
        if word is not None:
            lectureQueryset = Lecture.objects.all()
            lectureQueryset = lectureQueryset.filter(name__icontains=word)
            lecturesArray = []
            for lecture in lectureQueryset:
                lectureObject = {}
                lectureObject["name"] = lecture.name
                lectureObject["pk"] = lecture.pk
                lecturesArray.append(lectureObject)
        return JsonResponse({"lectures": lecturesArray},status=200)

That was the example code because of that I only returned 200. The most important thing is in this code is searching method which is name__icontains.

<!-- ~/search-bar.html -->

<form action={ % url 'ajax_search' %} id="ajax-search-form" method="POST" class="post-form">
    { % csrf_token %}
    <input name="search-value" id="ajax-search-value" style="width: 100%">
</form>
<div id="ajax-search-result-container" style="overflow-y: auto; max-height: 90px; margin-top: 10px;">
</div>

I made an form only with input for synchronous searching and I made container for showing results.

// ~/searchBarJavaScript.js

/*
 *
 *  Taking CSRF token for authorization
 *
 */
// CSRF Token Usage on Ajax from https://stackoverflow.com/questions/19333098403-forbidden-error-when-making-an-ajax-post-request-in-django-framework
// Getting token starts

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
var csrftoken = getCookie('csrftoken');

//Ajax call
function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// Getting token end

const searchForm = document.getElementById('ajax-search-form');
const searchButton = document.getElementById('ajax-search-button');
const url = searchForm.action;

const createAnchorsArray = (lectures) => {
    const anchors = [];
    for (lecture of lectures) {
        const anchor = document.createElement("a");
        anchor.href = `lecture/${lecture["pk"]}`
        anchor.innerHTML = `${lecture["name"]}`
        anchors.push(anchor)
    }

    return anchors;
}

const appendSearchResults = (anchors) => {
    const resultsContainer = document.getElementById("ajax-search-result-container");
    resultsContainer.innerHTML += "<br>"
    for (const anchor of anchors) {
        resultsContainer.append(anchor);
        resultsContainer.innerHTML += "<hr>"
    }
}

const submitFormFunction = () => {
    document.getElementById("ajax-search-result-container").innerHTML = "";

    $.ajaxSetup({
        crossDomain: false, // obviates need for sameOrigin test
        beforeSend: function(xhr, settings) {
            if (!csrfSafeMethod(settings.type)) {
                xhr.setRequestHeader("X-CSRFToken", csrftoken);
            }
        }
    });

    $.ajax({
        type: 'POST',
        url: url,
        data: {
            word: document.querySelector('#ajax-search-form #ajax-search-value').value
        },
        success: function(response) {
            const anchorsArray = createAnchorsArray(response["lectures"]);
            appendSearchResults(anchorsArray);
        },
        error: function(response) {
            console.warn(response.statusText);
        }
    })
}

searchForm.addEventListener("submit", function(event){
        event.preventDefault();
        submitFormFunction();
    }
)

document.querySelector('#ajax-search-form #ajax-search-value').addEventListener("keypress", function(event){
        submitFormFunction()
    }
)

I’m a lazy person because of that I took the generic taking csrf from stackoverflow.

# ~/urls.py

from django.conf.urls import url

urlpatterns = [
    # ...
	url('^ajax_search/$', views.ajax_search, name = "ajax_search"),
]

And I used this like this to every template:

{ % include 'ajax_search.html' %}