博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django笔记 3
阅读量:5223 次
发布时间:2019-06-14

本文共 5965 字,大约阅读时间需要 19 分钟。

接下来我们需要设计视图和页面了,一共要有四个视图:index,detail,vote,results,相应的也会有四个页面。

URL映射

首先需要解决的就是url映射,django在使用URL时首先找到ROOT_URLCONF这个设置(在settings.py里面),然后加载这个module,寻找里面的一个叫做urlpatterns的变量。它是一个元组,其中每一项的格式是“(regular expression,callback function[,optional dictionary])”。找到这个变量之后就从头到尾地进行匹配,匹配成功之后就调用回调函数,并将HttpRequest作为第一个参数。

在urls.py里添加关于投票的url映射信息:

urlpatterns = patterns(’’,url(r’^polls/$’, ’polls.views.index’),url(r’^polls/(?P
\d+)/$’, ’polls.views.detail’),url(r’^polls/(?P
\d+)/results/$’, ’polls.views.results’),url(r’^polls/(?P
\d+)/vote/$’, ’polls.views.vote’),url(r’^admin/’, include(admin.site.urls)),)

实现视图和模版

这里的所有view都没有实现,那么,下面就简单实现一下了:

from django.http import HttpResponsedef index(request):    return HttpResponse("Hello, world. You’re at the poll index.")def detail(request, poll_id):    return HttpResponse("You’re looking at poll %s." % poll_id)def vote(request, poll_id):    return HttpResponse("You’re voting on poll %s." % poll_id)def results(request, poll_id):    return HttpResponse("You’re looking at the results of poll %s." % poll_id)

这仅仅是个最简单的示例,以后还要一一实现。要注意,每一个view要么返回一个HttpResponse,要么抛出Http404异常。

index视图是用来显示投票列表的,为了不显示太多,我们把它修改为只显示最近的5个:

from django.http import HttpResponsefrom polls.models import Polldef index(request):    latest_poll_list=Poll.objects.all().order_by('-pub_date')[:5]    t=loader.get_template("polls/index.html")    c=Context({
'latest_poll_list':latest_poll_list,}) return HttpResponse(t.render(c))

这里用到的就是django里面的模版渲染:载入一个html模版,然后将context传入进去。context是一个字典,字典的项就是模版中要用到的变量。

我们之前设置过所有模版的根文件夹,即TEMPLATE_DIRS这个变量,只需要在下面建立polls/index.html就行了:

{% if latest_poll_list %}
{% else %}

No polls are available.

{% endif %}

如果现在运行服务器,就可以看到这个页面了,显示的内容就是所有的投票的问题。

两个捷径

第一个是django提供的模版渲染捷径:render_to_response()。这个方法有两个参数:模版页面和词典,因此上个例子可以改为:return render_to_response("polls/index.html",{'latest_poll_list':latest_poll_list})

在index页面的每一项会超连接到detail页面,首先会根据投票的id从数据库中找到相应的对象,当然,如果找不到就会抛出ObjectDoesNotExist异常,因此,detail视图应该是这样的:

def detail(request, poll_id):    try:        p=Poll.objects.get(pk=poll_id)    except Poll.DoesNotExist:        raise Http404    return render_to_response('polls/detail.html',{
'poll':p})

这就要引出我们说的第二个捷径了:get_object_or_404。它将一个model作为第一个参数,把get object时用到的一系列关键词作为第二个参数。因此上面的try except可以合并为一句:p = get_object_or_404(Poll, pk=poll_id)

要多说的是,如果真的出现了404错误,django就会调用URLConf中的handler404这个视图,你需要定义它,但如果没有,就默认调用django.views.defaults.page_not_found()这个视图。此外,还要自己实现一个404.html,因为本来没有这个页面,再加上DEBUG被设为False的话,就会产生HTTP500,500的意思是server error。当然,你也可以像404错误一样设定handler500.

改进URL映射

patterns的第一个参数的意思是下面所有view的共同前缀,因为关于投票的四个视图都以polls.views开头,因此可以改为:

urlpatterns = patterns(’polls.views’,url(r’^polls/$’, ’index’),url(r’^polls/(?P
\d+)/$’, ’detail’),url(r’^polls/(?P
\d+)/results/$’, ’results’),url(r’^polls/(?P
\d+)/vote/$’, ’vote’),)

但是admin和它们又没有共同前缀,因此可以写成这样:

urlpatterns = patterns(’polls.views’,url(r’^polls/$’, ’index’),url(r’^polls/(?P
\d+)/$’, ’detail’),url(r’^polls/(?P
\d+)/results/$’, ’results’),url(r’^polls/(?P
\d+)/vote/$’, ’vote’),)urlpatterns += patterns(’’,url(r’^admin/’, include(admin.site.urls)),)

前面说过,每一个application都是可插拔的,它独立于整个工程存在,但是这里的urls.py是在project文件夹下面的,也就是说,关于投票这个应用的url信息出现了工程的文件夹下。所以,为了实现松耦合,因此我们需要做一些改动:将mysite文件夹下的urls.py拷贝到polls文件夹下面,并将mysite/urls.py改为:

from django.conf.urls import patterns, include, urlfrom django.contrib import adminadmin.autodiscover()urlpatterns = patterns(’’,url(r’^polls/’, include(’polls.urls’)),url(r’^admin/’, include(admin.site.urls)),)

include语句调用了另一个URLConf,这时,django匹配过程变为首先找到polls/,如果匹配,将剩下的部分传递给引用的URLConf中。因此,polls/url.py应为:

from django.conf.urls import patterns, urlurlpatterns = patterns(’polls.views’,url(r’^$’, ’index’),url(r’^(?P
\d+)/$’, ’detail’),url(r’^(?P
\d+)/results/$’, ’results’),url(r’^(?P
\d+)/vote/$’, ’vote’),)

之前有一个模版文件index.html里用到了引用<a href="/polls/{

{ poll.id }}/">{
{ poll.question }}</a> ,现在应改为:<a href="{% url polls.views.detail poll.id %}">{
{poll.question}}</a>。django的url语法是这样的,{%url path-to-view args1 args2 %}.

更改detail模版

我们之前的polls/detail.html模版仅仅是显示出了问卷的问题,让我们把这个模版改一下,里面加上一个form表单:

{
{poll.question}}

{% if error_message %}

{

{ error_message }}

{% endif %}
{% csrf_token %}{% for choice in poll.choice_set.all %}
{% endfor %}

由于我们使用了csrf_token标签,因此就不能用context了,而要用RequestContext:

return render_to_response(’polls/detail.html’, {’poll’: p},context_instance=RequestContext

(request))

表单提交后到了vote视图:

def vote(request,poll_id):    #找到传进来的poll    p=get_object_or_404(Poll,pk=poll_id)    try:    #之前表单传入的参数是choice,值是choice_id,这里使用request.POST方法将它的值提取出来        selected_choice=p.choice_set.get(pk=request.POST['choice'])    #提取错误时,显示错误信息    except(KeyError,Choice.DoesNotExist):        return render_to_response('polls/detail.html',{        'poll':p,        'error_message':"You didn't select a choice.",        },context_instance=RequestContext(request))    #没有错误就给选中的那一项投一票,然后保存,将来写入到数据库中    else:        selected_choice.votes+=1        selected_choice.save()      #页面跳转到results视图        return HttpResponseRedirect(reverse('polls.views.results',args=(p.id,)))

reverse就是指定跳转的视图,定义是reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)。results视图用来显示结果:

def results(request,poll_id):    p=get_objects_or_404(Poll,pk=poll_id)    return render_to_response('polls/results.html',{
'poll':p})

results.html的内容:

{
{ poll.question }}

    {% for choice in poll.choice_set.all %}
  • {
    { choice.choice_text }} -- {
    { choice.votes}} vote{
    { choice.votes|pluralize }}
  • {% endfor %}
Vote again?

最后不说了,上图:

 

 

转载于:https://www.cnblogs.com/cubika/archive/2012/11/15/2772254.html

你可能感兴趣的文章
svn客户端清空账号信息的两种方法
查看>>
springboot添加servlet的两种方法
查看>>
java的Array和List相互转换
查看>>
layui父页面执行子页面方法
查看>>
如何破解域管理员密码
查看>>
Windows Server 2008 R2忘记管理员密码后的解决方法
查看>>
IE11兼容IE8的设置
查看>>
windows server 2008 R2 怎么集成USB3.0驱动
查看>>
Foxmail:导入联系人
查看>>
vue:axios二次封装,接口统一存放
查看>>
vue中router与route的区别
查看>>
js 时间对象方法
查看>>
网络请求返回HTTP状态码(404,400,500)
查看>>
Spring的JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate
查看>>
Mac下使用crontab来实现定时任务
查看>>
303. Range Sum Query - Immutable
查看>>
图片加载失败显示默认图片占位符
查看>>
【★】浅谈计算机与随机数
查看>>
《代码阅读方法与实现》阅读笔记一
查看>>
解决 sublime text3 运行python文件无法input的问题
查看>>