我想使用分页来列出数据库中的数据,但是当我点击下一页按钮时,它会显示“本地变量' 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>
答案 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)