django分页不能直接到下一页

时间:2018-01-24 13:01:56

标签: python django pagination

我想使用分页来列出数据库中的数据,但是当我点击下一页按钮时,它会显示“本地变量' context'在分配之前引用“

我首先使用过滤器从数据库中搜索数据,并使用" REQUSET.POST"把数据发回去。然后把数据发送到另一个html。我想当我点击下一页时,它会再次完成所有这些,但我不知道如何编码。

请帮我找出问题,谢谢!

以下是我的代码:

view.py

from django.template.loader import get_template
from django.template import RequestContext
from django.shortcuts import render,redirect
from django.http import HttpResponse,HttpResponseRedirect
from django.shortcuts import render,render_to_response
from datetime import datetime
from .form import DateRangeForm
from .models import Post
import tkinter.messagebox
from tkinter import *
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger
# Create your views here.

def answer():
    showerror("Answer", "Sorry, no answer available")

def homepage(request):
    posts = Post.objects.all()
    now = datetime.now()
    context = {'posts':posts,'now':now}
    return render(request,'jishi.html',context)

def showpost(request,times):
    template=get_template('post.html')
   ##posts=Post.objects.all().values('customer')
    posts=Post.objects.filter(pub_date__year=2018)
    now = datetime.now()
    html = template.render(locals())
    return HttpResponse(html)

def foobar(request):
    date_sel1 = request.POST.get('datetime1',None)
    date_sel2 = request.POST.get('datetime2',None)
    if date_sel1!=None:
        posts = Post.objects.filter(pub_date__range=(date_sel1,date_sel2)).order_by("pub_date","time")
        paginator = Paginator(posts,6,1)
        page = request.GET.get('page')
        try:
            customer = paginator.page(page)
        except PageNotAnInteger:
            customer = paginator.page(1)
        except EmptyPage:
            customer = paginator.page(paginator.num_pages)
        context={'posts':customer}
    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="?cur_page=1"><<</a></li>  
    <li>  
      <a href="?cur_page={{ posts.pre_page }}" aria-label="Previous">  
        <span aria-hidden="true">«</span>  
      </a>  
    </li>  
   {% endif %}  
   {% for num in posts.paginator.page_range %}  
    {% if num == posts.cur_page %}  
        <li><a href="?cur_page={{ num }}">{{ num }}</a></li>  
    {% else %}  
        <li><a href="?cur_page={{ num }}">{{ num }}</a></li>  
    {% endif %}  
   {% endfor%}  
   {% if posts.has_next %}  
    <li>  
      <a href="?cur_page={{ posts.next_page }}" aria-label="Next">  
        <span aria-hidden="true">»</span>  
      </a>  
    </li>  
    <li><a href="?cur_page={{ posts.all_page }}">>></a></li>  
   {% endif %}  
  </ul>  
</nav> 
{% endblock %}

“post”html的一部分

<form action="/blog/create/?cur_page=1" method ="post" class="form-horizontal"  role="form">{% csrf_token %}            
        <div class="form-group row">
            <label for="dtp_input1" class="col-sm-2 control-label text-lg-left" style='font-family:微软雅黑;font-size:10pt;'>开始日期</label>
            <div class="input-group date form_date1 col-sm-5">
                <input class="form-control" size="16" type="text" name="datetime1" value="2018-01-01" required title="3 characters minimum"><br>
                <span class="input-group-addon col-md-2"><span class="glyphicon align-middle glyphicon-remove"></span></span>                                           
            </div>
            <input type="hidden" id="dtp_input1" value="" /><br/>
        </div>
        <div class="form-group row">
            <label for="dtp_input2" class="col-sm-2 control-label text-lg-left" style='font-family:微软雅黑;font-size:10pt;'>结束日期</label>
            <div class="input-group date form_date2 col-sm-5">
                <input class="form-control" size="16" type="text" name="datetime2" value="2018-01-01" required title="3 characters minimum"><br>
                <span class="input-group-addon col-md-2"><span class="glyphicon align-middle glyphicon-remove"></span></span>                       
            </div>
            <input type="hidden" id="dtp_input2" value="" /><br/>
        </div>
        <div class="form-group row">
            <div class="col-sm-2">
                <button class="btn btn-primary" type="submit" name="search" style='font-family:微软雅黑;font-size:10pt;'>确认查询</button>  
            </div>
            <div class="col-sm-2">
                <button class="btn btn-primary" type="submit" name="count" style='font-family:微软雅黑;font-size:10pt;'>机时统计</button>   
            </div>
        </div>
</form>

1 个答案:

答案 0 :(得分:2)

下面:

def foobar(request):
    date_sel1 = request.POST.get('datetime1',None)
    date_sel2 = request.POST.get('datetime2',None)

您正在request.POST中查找过滤器的值。在GET请求中,我们不会设置这些内容,因此您将None作为date_sel1的值。然后:

if date_sel1!=None:
    # do some things here to get your data and:
    context={'posts':customer}
return render(request,'sheet.html',context)

这意味着当在同一视图上执行GET请求时 - 单击分页链接时会发生这种情况 - date_sel1为None,因此执行会直接跳转到return render(request,'sheet.html',context)语句。此时context尚未分配,因此该名称在本地范围内不存在。因此你获得了例外。

实际上,你不应该使用POST请求开始 - 搜索/过滤数据是幂等的(它不会改变服务器的状态),所以你想要使用GET相反(作为您的表单&#39;方法&#39;属性,以及查找查询参数的request属性)。这是官方正确的方式(并且作为一个附带的好处,它使您的搜索/过滤结果url bookmarkables和shareables,因为所有都在url的查询字符串中。)

然后,为了保持导航的一致性,您必须将搜索/过滤器参数(此处为&#39; datetime1&#39;和&#39; datetime2&#39;)添加回您的分页链接查询字符串。

最后,您的视图不应该依赖于在查询字符串中传递这些参数中的任何一个,也不应该假设如果设置了其中任何一个,那么另一个也被设置。如果你想要一个默认的未过滤的查询集,然后根据传递的查询args应用相关的过滤,然后只分页并填充你的上下文:

posts = Post.objects.all() # default

# NB : you're not using a Django form here (you really should)
# so what you will get are raw strings values, and possibly
# invalid ones. User inputs validation and sanitization is
# hard (and boring) so better let Forms take care of it, 
# that's what they are for.
date_sel1 = request.GET.get('datetime1',None)
date_sel2 = request.GET.get('datetime2',None)

if date_sel1 and date_sel2:
    # both where passed, filter on date range
    posts = posts.filter(pub_date__range=(date_sel1,date_sel2))
elif date_sel1:
    # only first argument was passed, filter on date_gte:
    posts = posts.filter(pub_date__gte=date_sel1)
elif date_sel2:
    # only first argument was passed, filter on date_lte:
    posts = posts.filter(pub_date__lte=date_sel2)
# ok no we have our possibly filtered queryset, let's order it
# and returns the result:

# XXX unrelated but it looks like you're using a DateField 
# and a distinct TimeField. Why not use a DatetimeField ?

posts = posts.order_by("pub_date","time")

paginator = Paginator(posts,6,1)
# XXX unrelated : better naming. `paginator.page(x)` 
# returns a `Page` object so why name it "customer" ?
pagenum = request.GET.get('page')
try:
    page = paginator.page(pagenum)
except PageNotAnInteger:
    page = paginator.page(1)
except EmptyPage:
    page = paginator.page(paginator.num_pages)

# populates the context with our page object 
# AND the (possibly empty) datetimeX values
# so we can add them to pagination links
# (and eventually display them to our user)
context={'posts':page, "datetime1": date_sel1,"datetime2": date_sel2}
return render(request,'sheet.html',context)