Django分页无法跳转下页,提示context变量未定义问题求助
解决Django分页的「context未定义」及参数丢失问题
看起来你踩了Django分页里两个常见的坑:一是视图逻辑没处理无参数的情况导致context未定义,二是分页时丢失了查询用的日期参数,还有模板里用错了分页对象的属性。我来一步步帮你修正:
一、先分析错误根源
- 「context referenced before assignment」错误:你的
foobar视图只有在POST提交日期参数时才会生成context并返回,但点击分页按钮是GET请求,此时request.POST里没有datetime1,代码不会进入if块,函数没有返回值,自然会报context未定义的错误。 - 分页参数丢失:分页是GET请求,第一次POST的日期参数不会自动携带到分页请求里,导致分页时无法重新筛选对应日期范围的数据。
- 模板分页属性错误:你用了
cur_page、pre_page这些Django分页对象不存在的属性,正确的属性是number(当前页)、previous_page_number(上一页)等。
二、修正视图函数foobar
把视图改成同时支持POST(提交日期)和GET(分页)请求,并且处理无参数的默认情况:
def foobar(request): # 同时从POST和GET获取日期参数,分页时用GET传递参数 date_sel1 = request.POST.get('datetime1') or request.GET.get('datetime1') date_sel2 = request.POST.get('datetime2') or request.GET.get('datetime2') # 处理查询逻辑:有日期参数则筛选,无参数则默认查所有数据 if date_sel1 and date_sel2: posts = Post.objects.filter(pub_date__range=(date_sel1, date_sel2)).order_by("pub_date", "time") else: # 无日期参数时的默认数据,可根据需求改成空查询或其他逻辑 posts = Post.objects.all().order_by("pub_date", "time") # 分页核心逻辑 paginator = Paginator(posts, 6, 1) # 每页展示6条数据 page = request.GET.get('page', 1) # 默认加载第1页 try: posts_page = paginator.page(page) except PageNotAnInteger: # 页码不是整数时返回第1页 posts_page = paginator.page(1) except EmptyPage: # 页码超出范围时返回最后一页 posts_page = paginator.page(paginator.num_pages) # 把日期参数传到模板,分页时要携带这些参数 context = { 'posts': posts_page, 'date_sel1': date_sel1, 'date_sel2': date_sel2 } return render(request, 'sheet.html', context)
三、修正HTML分页模板
主要是修正分页属性,并且在分页链接里带上日期参数,保证分页时查询条件不丢失:
{% extends 'balance.html' %} {% block content %} <div class='panel panel-default'> <div class='panel-heading'> <h3> 机时信息 </h3> </div> <div class="alert alert-warning" role="alert"> <table class="table table-bordered"> <thead> <tr> <th scope="col">条数</th> <th scope="col">日期</th> <th scope="col">时间</th> <th scope="col">客户</th> </tr> </thead> <tbody> {% for post in posts %} <tr> <th scope="row">{{forloop.counter}}</th> <td>{{post.pub_date|date:"Y-m-d D"}}</td> <td>{{post.time}}</td> <td>{{post.customer}}</td> </tr> {% endfor %} </tbody> </table> <h3><a href='/blog/'>回首页</a></h3> </div> </div> <nav aria-label="Page navigation"> <ul class="pagination"> {% if posts.has_previous %} <li><a href="?page=1&datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }}"><<</a></li> <li> <a href="?page={{ posts.previous_page_number }}&datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {% endif %} {% for num in posts.paginator.page_range %} {% if num == posts.number %} <li class="active"><a href="?page={{ num }}&datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }}">{{ num }}</a></li> {% else %} <li><a href="?page={{ num }}&datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }}">{{ num }}</a></li> {% endif %} {% endfor%} {% if posts.has_next %} <li> <a href="?page={{ posts.next_page_number }}&datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> <li><a href="?page={{ posts.paginator.num_pages }}&datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }}">>></a></li> {% endif %} </ul> </nav> {% endblock %}
模板里的关键修正点:
- 分页链接加上
datetime1={{ date_sel1 }}&datetime2={{ date_sel2 }},保留查询条件 - 用
posts.previous_page_number替代posts.pre_page,posts.number替代posts.cur_page,posts.next_page_number替代posts.next_page - 给当前页的
<li>加上active类,优化视觉效果
四、可选优化:表单提交路径
把查询表单的action改成空或者视图的命名URL(需要在urls.py里给foobar配置name='foobar'),这样提交后会停在当前页面,体验更流畅:
<form action="" method ="post" class="form-horizontal" role="form">{% csrf_token %}
内容的提问来源于stack exchange,提问作者Yang
相关产品推荐
相关产品推荐

