如何在django分页中实现Post/Redirect/Get?
How to implement Post/Redirect/Get in django pagination?
我有一个视图可以过滤掉已发布的搜索表单的结果:
def profile_advanced_search(request):
args = {}
if request.method == "POST":
form = AdvancedSearchForm(request.POST)
qs=[]
if form.is_valid():
cd = form.cleaned_data
s_country=cd['country']
s_province=cd['province']
s_city = cd['city']
if s_country: qs.append(Q(country__icontains = s_country))
if s_province: qs.append( Q(province__icontains=s_province))
if s_city: qs.append( Q(city__icontains=s_city))
f = None
for q in qs:
if f is None:
f=q
else: f &=q
list = UserProfile.objects.filter(f).order_by('-created_at')
else:
form = AdvancedSearchForm()
list = UserProfile.objects.all().order_by('-created_at')
paginator = Paginator(list,10)
page= request.GET.get('page')
try:
results = paginator.page(page)
except PageNotAnInteger:
results = paginator.page(1)
except EmptyPage:
results = paginator.page(paginator.num_pages)
args.update(csrf(request))
args['form'] = form
args['results'] = results
return render_to_response('userprofile/advanced_search.html', args,
context_instance=RequestContext(request))
urls.py 部分是:
url(r'^search/$', 'userprofile.views.profile_advanced_search'),
模板是:
<form action="/search/" method="post">{% csrf_token %}
<ul class="list-unstyled">
<li><h3>Country</h3></li>
<li>{{form.country}}</li><br>
<h4>Province</h4>
<li>{{form.province}}</li>
<h4>City</h4>
<li>{{form.city}}</li>
</ul>
<input type="submit" name="submit" value="search" />
</form>
Search Results:
{% for p in results %}
<div">
<div>
<br>
<strong><a href="/profile/{{p.username}}" >{{p.username}}</a></strong>
{{p.country}} <br>
{{p.province}} <br>
{{p.city}} <br>
</div>
</div>
{% endfor %}
<div>
<div class="pagination">
{% if results.has_previous %}
<a href="?page={{ results.previous_page_number }}"> << Prev </a>  
{% endif %}
{% if results.has_next %}
<a href="?page={{ results.next_page_number }}"> Next >> </a>
{% endif %}
</div>
</div>
</div>
这些对于第一页工作正常,但要处理后面的页面,我需要实现 Post/Redirect/Get 。
但是我很难views/template/urls处理GET页面,因为所有搜索参数都是任意的。所以我很欣赏一个完整的解决方案。
您需要 2 次观看。第一个用于表单搜索,第二个用于显示结果。您还没有在示例代码中以任何方式实现重定向!
网址
...
url(r'^search/$',
'userprofile.views.profile_advanced_search'),
url(r'^show/(?P<country>\w+)/(?P<province>\w+)/(?P<site>\w+)/(?P<page>\d+)',
'userprofile.views.profile_advanced_show'),
...
profile_advanced_search
def profile_advanced_search(request):
args = {}
if request.method == "POST":
form = AdvancedSearchForm(request.POST)
qs=[]
if form.is_valid():
cd = form.cleaned_data
s_country=cd['country']
s_province=cd['province']
s_city = cd['city']
return HttpResponseRedirect(
reverse('userprofile.views.profile_advanced_show',
args=(s_country, s_province, s_city, 0, )))
return HttpResponseRedirect(
reverse('userprofile.views.profile_advanced_show',
args=('+', '+', '+', 0, )))
profile_advanced_show
def profile_advanced_show(request, s_country='',
s_province='', s_city='', page=0):
f = some filters with s_country, s_province and s_city
list = UserProfile.objects.filter(f).order_by('-created_at')
paginator = Paginator(list,10)
try:
results = paginator.page(page)
except PageNotAnInteger:
results = paginator.page(1)
except EmptyPage:
results = paginator.page(paginator.num_pages)
args.update(csrf(request))
form = AdvancedSearchForm(initial={ 's_country': s_country, ... } )
args['form'] = form
args['results'] = results
return render_to_response('userprofile/advanced_search.html', args,
context_instance=RequestContext(request))
注意:针对无效的表单提交进行改进。请记住,您可以通过 GET 将参数作为键值而不是路由值发送到第二个视图。
我有一个视图可以过滤掉已发布的搜索表单的结果:
def profile_advanced_search(request):
args = {}
if request.method == "POST":
form = AdvancedSearchForm(request.POST)
qs=[]
if form.is_valid():
cd = form.cleaned_data
s_country=cd['country']
s_province=cd['province']
s_city = cd['city']
if s_country: qs.append(Q(country__icontains = s_country))
if s_province: qs.append( Q(province__icontains=s_province))
if s_city: qs.append( Q(city__icontains=s_city))
f = None
for q in qs:
if f is None:
f=q
else: f &=q
list = UserProfile.objects.filter(f).order_by('-created_at')
else:
form = AdvancedSearchForm()
list = UserProfile.objects.all().order_by('-created_at')
paginator = Paginator(list,10)
page= request.GET.get('page')
try:
results = paginator.page(page)
except PageNotAnInteger:
results = paginator.page(1)
except EmptyPage:
results = paginator.page(paginator.num_pages)
args.update(csrf(request))
args['form'] = form
args['results'] = results
return render_to_response('userprofile/advanced_search.html', args,
context_instance=RequestContext(request))
urls.py 部分是:
url(r'^search/$', 'userprofile.views.profile_advanced_search'),
模板是:
<form action="/search/" method="post">{% csrf_token %}
<ul class="list-unstyled">
<li><h3>Country</h3></li>
<li>{{form.country}}</li><br>
<h4>Province</h4>
<li>{{form.province}}</li>
<h4>City</h4>
<li>{{form.city}}</li>
</ul>
<input type="submit" name="submit" value="search" />
</form>
Search Results:
{% for p in results %}
<div">
<div>
<br>
<strong><a href="/profile/{{p.username}}" >{{p.username}}</a></strong>
{{p.country}} <br>
{{p.province}} <br>
{{p.city}} <br>
</div>
</div>
{% endfor %}
<div>
<div class="pagination">
{% if results.has_previous %}
<a href="?page={{ results.previous_page_number }}"> << Prev </a>  
{% endif %}
{% if results.has_next %}
<a href="?page={{ results.next_page_number }}"> Next >> </a>
{% endif %}
</div>
</div>
</div>
这些对于第一页工作正常,但要处理后面的页面,我需要实现 Post/Redirect/Get
但是我很难views/template/urls处理GET页面,因为所有搜索参数都是任意的。所以我很欣赏一个完整的解决方案。
您需要 2 次观看。第一个用于表单搜索,第二个用于显示结果。您还没有在示例代码中以任何方式实现重定向!
网址
...
url(r'^search/$',
'userprofile.views.profile_advanced_search'),
url(r'^show/(?P<country>\w+)/(?P<province>\w+)/(?P<site>\w+)/(?P<page>\d+)',
'userprofile.views.profile_advanced_show'),
...
profile_advanced_search
def profile_advanced_search(request):
args = {}
if request.method == "POST":
form = AdvancedSearchForm(request.POST)
qs=[]
if form.is_valid():
cd = form.cleaned_data
s_country=cd['country']
s_province=cd['province']
s_city = cd['city']
return HttpResponseRedirect(
reverse('userprofile.views.profile_advanced_show',
args=(s_country, s_province, s_city, 0, )))
return HttpResponseRedirect(
reverse('userprofile.views.profile_advanced_show',
args=('+', '+', '+', 0, )))
profile_advanced_show
def profile_advanced_show(request, s_country='',
s_province='', s_city='', page=0):
f = some filters with s_country, s_province and s_city
list = UserProfile.objects.filter(f).order_by('-created_at')
paginator = Paginator(list,10)
try:
results = paginator.page(page)
except PageNotAnInteger:
results = paginator.page(1)
except EmptyPage:
results = paginator.page(paginator.num_pages)
args.update(csrf(request))
form = AdvancedSearchForm(initial={ 's_country': s_country, ... } )
args['form'] = form
args['results'] = results
return render_to_response('userprofile/advanced_search.html', args,
context_instance=RequestContext(request))
注意:针对无效的表单提交进行改进。请记住,您可以通过 GET 将参数作为键值而不是路由值发送到第二个视图。