Ajax живой поиск в заголовке на wagtail/Django
Недавно я только начал изучать Python, Wagtail и Django. Возникла необходимость создать живой поиск в шапке сайта, но я никак не могу заставить его работать корректно; в результате поиска загружается вся страница с результатами поиска.
Вот код, на который я потратил много сил:
в файле header.html:
<div class="block_search">
<input type="text" class="search_input searchbox" id="search_header" value="" placeholder="Поиск товара..." name="q" >
{% include "tags/header_search.html" %}
</div>
header_search.html:
{% load static wagtailcore_tags header_tags %}
<div id="search_box-result">
{% get_header_search as search_result%}
{% for result in search_result %}
{{result.title}}
{% endfor %}
</div>
Jquery:
<script>
$(document).ready(function () {
$('#search_header').on('input',function(e){
var search_result = $("#search_header").val();
$.ajax({
type: 'GET',
cache: true,
url: '',
data: {"search": search_result},
success: function (response) {
$("#search_box-result").replaceWith(response)
}
});
});
});
</script>
header_tags.py:
@register.simple_tag(takes_context=True)
def get_header_search(context):
request = context['request']
if request.method == 'GET':
search_query = request.GET.get("search", None)
print(search_query)
if search_query:
search_results = Page.objects.live().search(search_query)
else:
search_results = Page.objects.none()
return search_results
В браузере: введите описание изображения здесь
введите описание изображения здесь
Я думаю, что вам нужен способ определить, где находится вызов ajax или пользовательский вызов из браузера. Мне это тоже нужно. Рассматривая, в чем разница между ajax и пользовательским запросом браузера, я нашел эту ссылку. Когда я смог отличить эти вызовы, я сделал такой код:
def is_ajax(request):
if(request.headers.get('SEC_FETCH_SITE') == "same-origin"):
return True
return False
class Model(Page):
description = models.CharField(max_length=511)
def get_template(self, request):
if is_ajax(request):
return "base/model_ajax.html"
return "base/model_page.html"
Когда вы просматриваете тег get_header_search, вы можете определить, является ли он ajax или нет. Возможно, если это ajax, вы можете использовать другой шаблон или JsonResponse, а если нет, то можно загрузить другой шаблон.
Когда вы запрашиваете с помощью ajax, вам нужен URL, этот url в wagtail может быть синтаксисом API Wagtail или просто статическим url, который может быть отображен с помощью контекстного процессора django. В моем случае это был статический URL, отображаемый внутри шаблона, когда я нажимал на него, я делал ajax вызов документа, специально предназначенного для шаблона, а когда его не было. Я просто поместил обычный шаблон.
Надеюсь, это поможет.
мое решение проблемы
В Wagtail есть ajax_template, он задает шаблон, который будет отвечать на любой Ajax-запрос, но задает один шаблон. Я переопределил функцию получения шаблона и, в зависимости от запроса get, отображаю нужный шаблон.
Я не знаю, насколько это правильно, но это работает без проблем.
class CategoryPage(Page):
parent_page_types = ['catalog.CatalogPage','category.CategoryPage']
subpage_types = ['category.CategoryPage','product.ProductPage']
def get_template(self, request, *args, **kwargs):
if request.headers.get("x-requested-with") == "XMLHttpRequest":
if request.GET.get("search", None) != None:
self.ajax_template = 'tags/header_search.html'
elif request.GET.getlist('platforms_ids[]', None) != None or request.GET.getlist('types_ids[]', None) != None or request.GET.get('page[]', 1) != None:
self.ajax_template = "tags/category_filtered_products_for_ajax.html"
return self.ajax_template or self.template
else:
return self.template