Reputation: 555
I was trying to implement on keyup search with django and jquery following this video
but when I try the code everytime it returns forbidden 403!
the html page:
<div class="search-input">
<form>
{% csrf_token %}
<button>بحـث</button>
<input
type="text"
name="q"
id="search"
placeholder="Est: Game of thrones, Vikings or Deadpool"
/>
</form>
</div>
<div class="search-results"></div>
urls.py:
path('search/', views.search_titles, name='search')
views.py:
def search_titles(request):
if request.method == 'POST':
search_text = request.POST['search_text']
else:
search_text = ''
search_results = Media.objects.filter(
is_published=True, title__contains=search_text)[:5]
context = {
'search_results': search_results
}
return render(request, 'partials/_search_results.html', context)
the jquery file:
$("#search").on("keyup", function() {
$.ajax({
type: "POST",
url: "/search/",
data: {
search_text: $("#search").val(),
csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val()
},
success: searchSuccess,
dataType: "html"
});
});
function searchSuccess(data, textStatus, jqXHR) {
$("search-results").html(data);
}
});
search_results.html ( that i don't even know the reason of )
{% if search_results.count > 0 %} {% for result in search_results %}
<li>
<a href="#">{{ result.title }}</a>
</li>
{% endfor %} {% else %}
<li>Nothing to show</li>
{% endif %}
Upvotes: 1
Views: 1388
Reputation: 2084
This is likely happening because you are not properly setting up AJAX to pass your CSRF token. The Django docs have a great section on how to set this up. Here's the short story.
First, you'll need to acquire the token:
Here's how to do it if CSRF_USE_SESSIONS and CSRF_COOKIE_HTTPONLY in your settings are False:
// using jQuery
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');
// using jQuery
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');
OR, Here's how to do it if CSRF_USE_SESSIONS or CSRF_COOKIE_HTTPONLY in your settings are True:
{% csrf_token %}
<script type="text/javascript">
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
</script>
IN BOTH CASES, you'll also need to set up the token on your AJAX request:
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
Upvotes: 1