【发布时间】:2021-08-16 15:01:06
【问题描述】:
当您在具有分页功能的 Django 应用程序中使用 ajax 进行搜索时,我正在实现一种类型。我希望在用户在数据库中键入他们的搜索词而不是带有提交按钮的表单时刷新结果。我正在使用 Django 的内置分页对数据进行分页并在模板中显示。
现在:
- HTTP GET 参数在 Django 视图中处理,并使我们的视图捕获用户的查询。
- Django 视图处理 Ajax 请求并使用包含新(模板)结果的 JSON 响应正确响应它们。
- 一旦用户开始在 HTML 搜索框中输入内容,JavaScript 和 jQuery 就会向我们的视图发送 Ajax 请求。
- 此请求将包含术语,以便服务器可以返回相关结果。
- 一旦我们的视图返回 JSON 响应,我们的 JS 代码将使用它来更改呈现给用户的信息,而无需刷新页面。
问题:
目前,当我收到我的搜索结果并转到第二页时,我收到了与我认为丢失的搜索查询无关的结果。 例如搜索“约翰”,我有一个以“约翰”为名称的对象(艺术家姓名)列表。当我因为 John 的页面很多而按下一页时,我丢失了这个“John”查询,它显示了我所有艺术家列表的第二页,而忽略了我的搜索参数 john。
有没有办法对我的结果进行分页,而不会在我更改页面时重新加载(动态加载)并丢失我的 URL 查询“John”?
(js.html 文件有指向artist.js 文件的链接,并通过CDN 托管jquery)
views.py
'''
from django.template.loader import render_to_string
from django.http import JsonResponse
def artist_list(request):
url_parameter = request.GET.get('q')
if url_parameter:
artists = Pagination(request, Artist.objects.filter(name__icontains=url_parameter)
else:
artists = Pagination(request, Artist.objects.all()
if request.is_ajax():
html = render_to_string(
template_name='artist_replaceable_content.html', context={'artists': artists}
)
data_dict = {'html_from_view': html}
return JsonResponse(data=data_dict, safe=False)
return render(request, 'artist.html', context={'artists': artists})
'''
艺术家.html
'''
{% load static %}
{% load crispy_forms_tags %}
{% block content %}
{% include "css.html" %}
<div class="container-fluid bg-soft">
<main class="content">
<h2 class="h4">Artist_List</h2>
<div class="input-group">
<div class="input-group-prepend"><span class="input-group-text"><span class="fas fa-search" id="search-icon"></span></span>
</div>
<input class="form-control" id="searchInput" name='Search' placeholder="Search" type="text" aria-label="user search">
</div>
<div class="border bg-white" id="replaceable-content">
{% include 'artist_replaceable_content.html' %}
</div>
</main>
</div>
{% include "js.html" %}
{% endblock %}
'''
artist_replaceable_content.html
'''
{% load static %}
{% if artists %}
{% for artist in artists %}
<div class="card hover-state">
<h3 class="h5">{{ artists.title }}</h3>
</div>
{% endfor %}
{% else %}
<span class="font-weight-normal text-gray">No artists found!</span>
{% endif %}
<div class="card-footer">
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if artists.has_other_pages %}
{% if artists.has_previous %}
<li class="page-item"><a class="page-link" href="page=1">First</a></li>
<li class="page-item"><a class="page-link" href="?page={{ artists.previous_page_number }}">Previous</a></li>
{% endif %}
{% for i in artists.paginator.page_range %}
{% if artists.number == i %}
<li class="page-item active"><a class="page-link" href="?page={{ i }}">{{ i }}</a></li>
{% elif i > artists.number|add:'-5' and i < artists.number|add:'5' %}
<li class="page-item"><a class="page-link" href="?page={{ i }}">{{ i }} </a></li>
{% endif %}
{% endfor %}
{% if artists.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ artists.next_page_number }}">Next</a></li>
{% endif %}
{% endif %}
</ul>
</nav>
<div class="font-weight-bold small">Showing<b>{{ artists.start_index {{artists.end_index }}</b> out of <b>{{ artists.paginator.count }}</b> entries</div>
</div>
'''
艺术家.js:
'''
$(document).ready(function() {
const search_Input = $("#searchInput")
const artists_content = $('#replaceable-content')
const search_icon = $('#search-icon')
const endpoint = '/artists/'
const delay_by_in_ms = 700
let scheduled_function = false
// getJSON() method to send an Ajax request to the endpoint alongside the parameters.
let ajax_call = function (endpoint, request_parameters) {
$.getJSON(endpoint, request_parameters)
.done(response => {
// fade out artists_content, replace and fade in artists_content
artists_content.fadeTo('fast', 0).promise().then(() => {
artists_content.html(response['html_from_view'])
artists_content.fadeTo('fast', 1)
})
})
}
// start
search_Input.on('keyup', function () {
event.preventDefault();
const request_parameters = {
q: $(this).val() // value of user_input: the HTML element with ID user-input
}
// if scheduled_function is NOT false, cancel the execution of the function
if (scheduled_function) {
clearTimeout(scheduled_function)
}
// setTimeout returns the ID of the function to be executed
scheduled_function = setTimeout(ajax_call, delay_by_in_ms, endpoint, request_parameters)
})
});
''' urls.py
'''
from django.urls import path
from core import views as core_views
urlpatterns = [
path("artists/", core_views.artists_view, name="artists"),
]
'''
【问题讨论】:
标签: javascript jquery django ajax pagination