本教程从随笔停止的地方开始。这次重点放在视图上。
概述
视图是应用程序网页的类型,通常用于特点功能并具有模板。在django中,网页和其他内容由视图传递。每个视图由一个python函数表示。通过检查url来选择一个视图。
写更多的意见
在polls/vies.py文件中添加视图:
1 def index(request): 2 return HttpResponse("Hello,world. You're at the polls index") 3 4 def detail(request,question_id): 5 return HttpResponse('You are looking question %s.'%question_id) 6 7 def results(request,question_id): 8 response='You are looking at the result of question %s.' 9 return HttpResponse(response%question_id) 10 11 def vote(request,question_id): 12 return HttpResponse('You are voting on question %s.'%question_id)
之后这些视图都要匹配正则。在polls/urls.py文件编写代码:
1 urlpatterns=[ 2 url(r'^$',views.index,name='index'), #/polls/ 3 url(r'^(?P<question_id>[0-9]+)/$',views.detail,name='detail'), #/polls/5/ 4 url(r'^(?P<question_id>[0-9]+)/results/$',views.results,name='results'), #/polls/5/results/ 5 url(r'^(?P<question_id>[0-9]+)/vote/$',views.vote,name='vote'), #/polls/5/vote/ 6 ]
现在来测试一下吧。启动服务器。
添加的三个视图完美匹配!
说明:当有人访问你的网站请求一个页面时,比如/polls/34/时,django会加载mysite/urls模块。从urlpatterns当中按顺序匹配。找到匹配'^polls/'后。会去掉匹配的文本。将剩余的文本"34/"发送到polls.urls进一步处理。在那边匹配urlpatterns。后面就调用了detail()视图。
detail(request=<HttpRequest object>,question_id=‘34’)
该函数的第二个参数部分来自(?P<question_id>[0-9]+)。?P<question_id>表示匹配模式的名称,[0-9]+则是一个正则表达式。
编写实际执行某些操作的视图
polls/views.py文件:
def index(request): latest_question_list=Question.objects.order_by('-pub_date')[:5] output=', '.join([q.question_text for q in latest_question_list]) return HttpResponse(output)这里
如果你想改变页面的外观,你可以在polls目录下创建一个templates文件夹。顺便创建在模版目录下创建polls文件夹用于存放html代码。
polls/templates/polls/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello</title> </head> <body> {% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id}}/">{{ question.question_text }}</a></li> {% endfor %} </ul> {% else %} <p>No polls are available {% endif %} </body> </html>
模版写了,要把他渲染出来,回到视图:
def index(request): latest_question_list=Question.objects.order_by('-pub_date')[:5] context={ 'latest_question_list':latest_question_list } return render(request,'polls/index.html',context) #第一个参数:请求对象 #第二个参数:模板名称 #第三个参数:字典
浏览器显示效果:
引发404错误:
http404如果请求的ID的问题不存在,则视图引发异常。
在视图中修改detail.html:
from django.shortcuts import render,get_object_or_404 def detail(request,question_id): question=get_object_or_404(Question,pk=question_id) return render(request,'polls/detail.html',{'question':question})
detail.html暂时添加 :{{ question }}
该get_object_or_404()函数将django模型作为其第一个参数和任意数量的关键字参数,并将其传递给get()模型管理器的函数。Http404如果对象不存在,则会引发
另外还有一个get_list_or_404()功能,但是是使用了filter()而不是get()。如果列表为空,则引发Http404。
使用模版系统
回到detail.html中
<body> <h1>{{ question.question_text }}</h1>> <ul> {{% for choice in question.choice_set.all }} <li>{{ choice.choice_text }}</li> {% endfor %} </ul> </body>
删除硬编码的网站模版
在polls/index.html中。有段代码:
<li><a href="/polls/{{ question.id}}/">{{ question.question_text }}</a></li>
这种硬编码,紧密耦合的方法存在的问题,在具有大量模版的项目上更改网址极具挑战性。
但是由于url()在polls.urls模块中的函数定义了name参数,因此可以使用模版标记删除对url配置中定义特定的url路径的依赖:{% url %}
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
命名空间URL名称
该教程项目只有一个应用程序,polls。在真正的django项目中,可能会有五个,十个,二十个应用程序或更多。django如何区分url名称?
例如,polls应用程序有一个detail视图,同一个项目的另一个应用程序也可以用于博客。将命名空间添加到urlconf中。
polls/urls.py,继续添加一个app_name。
同时修改polls/index.html
其实。我有点弄不懂为啥要这样做。我认为前面的urlconf是在polls应用程序下。就算你有十几个应用程序。那也是和polls同级。在项目下的url匹配就已经区分开了呀!
你换成其他项目,那就不会匹配到polls.urls了。弄不懂弄不懂弄不懂!!!