【发布时间】:2017-03-04 20:31:07
【问题描述】:
我几天来一直试图弄清楚这一点,但无法在网上找到任何有用的信息。 我想要做的是在使用下拉菜单过滤对象并通过 AJAX 将数据提供给 python 之后对模型中的对象进行分页。我知道问题出在哪里,但我不知道如何解决它。我有两个模板,第一个是:
entry_index.html:
{% extends 'main/base.html' %}
<form action="" method="get" accept-charset="utf-8">
<select class="selectpicker" name="times" onchange="FilterCategories()" id="times">
<option value="1">last 24 hours</option>
<option value="30">past month</option>
<option value="365">past year</option>
<option value="10000">all time</option>
</select>
</form>
<ul id="all-games" class="list-unstyled">
{% include page_template %}
</ul>
上述模板中包含的模板是entry_index_page.html:
{% if objects %}
{% for object in objects %}
do something
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if objects.has_previous %}
<a href="?page={{ objects.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ objects.number }} of {{ objects.paginator.num_pages }}.
</span>
{% if objects.has_next %}
<a href="?page={{ objects.next_page_number }}">next</a>
{% endif %}
</span>
</div>
urls.py:
url(r'^$', views.entry_index, name='index')
views.py:
def entry_index(
request,
template='entry_index.html',
page_template='entry_index_page.html'):
date_from = timezone.now() - timezone.timedelta(days=1)
obj_list=Object.objects.filter(submitted__gte = date_from).order_by('-votes')
message=[]
context = {
'objects': obj_list,
'page_template': page_template}
if request.is_ajax():
template = page_template
message = []
if request.method == "GET":
time_range = request.GET.get('time_range')
if time_range is not None and time_range != u"":
time_range = request.GET['time_range']
date_from = timezone.now() - timezone.timedelta(days=int(time_range))
obj_list= Object.objects.filter.filter(submitted__gte=date_from)
paginator = Paginator(obj_list, 2)
page = request.GET.get('page')
try:
objects= paginator.page(page)
except PageNotAnInteger:
objects= paginator.page(1)
except EmptyPage:
objects= paginator.page(paginator.num_pages)
context.update({"message":message,"objects":objects})
return render_to_response(
template, context, context_instance=RequestContext(request))
ajax.js:
function FilterCategories() {
var timePosted = document.getElementById('times');
$.ajax({
type: "GET",
url: "",
data: {
'time_range': timePosted.value,
'csrfmiddlewaretoken': $("input[csrfmiddlewaretoken]").val()
},
success: filterResults,
dataType: 'html'
});
}
现在解释一下我的想法,希望有人可以帮助我找到解决方案。
加载主页 (entry_index.html) 时,模型会根据下拉菜单中的第一个选项进行过滤(即 value="1",用于过滤最后一天提交的数据条目)。 obj_list 变量被填充并传递给分页器,一切都按预期工作。我得到了一定数量的页面,并且可以浏览页面。现在假设我们再次在主页上,我从下拉菜单中选择“所有时间”。这将触发 onchange 回调并调用 FilterCategories() 函数。注意 AJAX 中的 url 是 "" (一个空字符串,所以指向我的索引页)。根据 urls.py,它会调用我的 entry_index() 视图。因为request是ajax,所以使用的模板会发生变化(page_template变成了新的模板,page_template = entry_index_page.html)。因为使用下拉菜单指定的新时间范围并使用 ajax 传递,所以我得到一个新的 obj_list,然后对其进行分页并生成“对象”,然后将其作为上下文传递给模板。到目前为止,一切都按预期工作。我得到了适量的页面等。但是,当我尝试使用新选择的过滤器转到下一页时,问题就开始了。当我单击下一页按钮时,正在发出的请求不是 ajax 请求,因此 request.is_ajax() 条件中的所有内容都不会执行。所以换句话说,点击下一页再次调用我的 entry_index 视图,这次使用的模板是 entry_index.html,我的过滤器被重置为默认值,即“过去 24 小时”过滤器。因此,当我单击下一页时,我最终得到的实际上是默认主页,而不是使用我新选择的下拉过滤器获取下一页对象。
我的问题是,有没有一种简单的方法可以解决这个问题,以便我可以滚动浏览过滤模型的页面?还是我应该完全放弃这种方法,并且有更简单的方法可以做到这一点?我为一个长帖子道歉,我希望那里的人能够帮助我。感谢您花时间阅读本文。
【问题讨论】:
-
我并不完全遵循您的流程,但您可能会发现使用单个模板更容易,只需使用 AJAX 替换页面本身的数据或 HTML 块,而不是创建新页面负载。它会更快,移动部件更少。